{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- | The Leios types that the storage layer needs: hashes, points, endorser
-- block bodies and their sizes.
--
-- This is the slice of the Leios prototype's types that
-- "Ouroboros.Consensus.Storage.LeiosDB" depends on. The rest of the Leios
-- machinery (announcements, fetch, voting, certificates) extends this module
-- as it lands.
module Ouroboros.Consensus.Leios.Types
  ( -- * Hashes
    EbHash (..)
  , encodeEbHash
  , decodeEbHash
  , prettyEbHash
  , RbHash (..)
  , encodeRbHash
  , decodeRbHash
  , prettyRbHash
  , TxHash (..)
  , prettyTxHash

    -- * Points
  , LeiosPoint (..)
  , encodeLeiosPoint
  , decodeLeiosPoint
  , prettyLeiosPoint

    -- * Elections
  , ElectionId (..)

    -- * Votes
  , LeiosVote (..)
  , encodeLeiosVote
  , decodeLeiosVote

    -- * Endorser blocks
  , BytesSize
  , LeiosEb (..)
  , leiosEbBodyItems
  , encodeLeiosEb
  , encodeLeiosEbItemSize
  , encodeLeiosEbMaxFramingSize
  , encodeLeiosEbSize
  , leiosReferencesCapacity

    -- * Header checks
  , milliseconds32ToNominalDiffTime
  , minCertificationSlot
  ) where

import Cardano.Binary.FixedSizeCodec (decodeFixedSized, encodeFixedSized)
import Cardano.Crypto.Leios (LeiosSeatId (..), LeiosSignature)
import Cardano.Crypto.Util (SignableRepresentation (..))
import Cardano.Ledger.BaseTypes (Milliseconds32 (..))
import Cardano.Ledger.Binary.Plain (decodeRecordNamed)
import Cardano.Ledger.Keys (KeyHash, KeyRole (BlockIssuer))
import Cardano.Slotting.Slot (SlotNo (..))
import Cardano.Slotting.Time (SlotLength, slotLengthToMillisec)
import Codec.CBOR.Decoding (Decoder)
import qualified Codec.CBOR.Decoding as CBOR
import Codec.CBOR.Encoding (Encoding)
import qualified Codec.CBOR.Encoding as CBOR
import Codec.CBOR.Write (toStrictByteString)
import Codec.Serialise (Serialise (..))
import Control.DeepSeq (NFData)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Base16 as BS16
import qualified Data.ByteString.Char8 as BS8
import Data.Foldable (toList)
import Data.Function ((&))
import qualified Data.Text as T
import Data.Time (NominalDiffTime)
import Data.Vector.Strict (Vector)
import qualified Data.Vector.Strict as V
import Data.Word (Word32)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)
import Ouroboros.Consensus.Ledger.SupportsMempool (ByteSize32 (..))
import Ouroboros.Consensus.Util (ShowProxy (..))

-- * Hashes

-- | Hash of an Endorser Block
newtype EbHash = MkEbHash {EbHash -> ByteString
ebHashBytes :: ByteString}
  deriving newtype (EbHash -> EbHash -> Bool
(EbHash -> EbHash -> Bool)
-> (EbHash -> EbHash -> Bool) -> Eq EbHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EbHash -> EbHash -> Bool
== :: EbHash -> EbHash -> Bool
$c/= :: EbHash -> EbHash -> Bool
/= :: EbHash -> EbHash -> Bool
Eq, Eq EbHash
Eq EbHash =>
(EbHash -> EbHash -> Ordering)
-> (EbHash -> EbHash -> Bool)
-> (EbHash -> EbHash -> Bool)
-> (EbHash -> EbHash -> Bool)
-> (EbHash -> EbHash -> Bool)
-> (EbHash -> EbHash -> EbHash)
-> (EbHash -> EbHash -> EbHash)
-> Ord EbHash
EbHash -> EbHash -> Bool
EbHash -> EbHash -> Ordering
EbHash -> EbHash -> EbHash
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: EbHash -> EbHash -> Ordering
compare :: EbHash -> EbHash -> Ordering
$c< :: EbHash -> EbHash -> Bool
< :: EbHash -> EbHash -> Bool
$c<= :: EbHash -> EbHash -> Bool
<= :: EbHash -> EbHash -> Bool
$c> :: EbHash -> EbHash -> Bool
> :: EbHash -> EbHash -> Bool
$c>= :: EbHash -> EbHash -> Bool
>= :: EbHash -> EbHash -> Bool
$cmax :: EbHash -> EbHash -> EbHash
max :: EbHash -> EbHash -> EbHash
$cmin :: EbHash -> EbHash -> EbHash
min :: EbHash -> EbHash -> EbHash
Ord, Context -> EbHash -> IO (Maybe ThunkInfo)
Proxy EbHash -> String
(Context -> EbHash -> IO (Maybe ThunkInfo))
-> (Context -> EbHash -> IO (Maybe ThunkInfo))
-> (Proxy EbHash -> String)
-> NoThunks EbHash
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> EbHash -> IO (Maybe ThunkInfo)
noThunks :: Context -> EbHash -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> EbHash -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> EbHash -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy EbHash -> String
showTypeOf :: Proxy EbHash -> String
NoThunks, [EbHash] -> Encoding
EbHash -> Encoding
(EbHash -> Encoding)
-> (forall s. Decoder s EbHash)
-> ([EbHash] -> Encoding)
-> (forall s. Decoder s [EbHash])
-> Serialise EbHash
forall s. Decoder s [EbHash]
forall s. Decoder s EbHash
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: EbHash -> Encoding
encode :: EbHash -> Encoding
$cdecode :: forall s. Decoder s EbHash
decode :: forall s. Decoder s EbHash
$cencodeList :: [EbHash] -> Encoding
encodeList :: [EbHash] -> Encoding
$cdecodeList :: forall s. Decoder s [EbHash]
decodeList :: forall s. Decoder s [EbHash]
Serialise)
  deriving stock (forall x. EbHash -> Rep EbHash x)
-> (forall x. Rep EbHash x -> EbHash) -> Generic EbHash
forall x. Rep EbHash x -> EbHash
forall x. EbHash -> Rep EbHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EbHash -> Rep EbHash x
from :: forall x. EbHash -> Rep EbHash x
$cto :: forall x. Rep EbHash x -> EbHash
to :: forall x. Rep EbHash x -> EbHash
Generic

instance Show EbHash where
  show :: EbHash -> String
show = EbHash -> String
prettyEbHash

encodeEbHash :: EbHash -> Encoding
encodeEbHash :: EbHash -> Encoding
encodeEbHash (MkEbHash ByteString
bytes) = ByteString -> Encoding
CBOR.encodeBytes ByteString
bytes

decodeEbHash :: Decoder s EbHash
decodeEbHash :: forall s. Decoder s EbHash
decodeEbHash = ByteString -> EbHash
MkEbHash (ByteString -> EbHash) -> Decoder s ByteString -> Decoder s EbHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s ByteString
forall s. Decoder s ByteString
CBOR.decodeBytes

prettyEbHash :: EbHash -> String
prettyEbHash :: EbHash -> String
prettyEbHash (MkEbHash ByteString
bytes) = ByteString -> String
BS8.unpack (ByteString -> ByteString
BS16.encode ByteString
bytes)

-- | Hash of a Ranking Block
--
-- A Ranking Block is the Praos Block. While the regular Praos headers are parameterised
-- over 'blk', we choose to keep 'RbHash' monomorphic. Use the 'ConvertRawHash' type class
-- to convert between this type and 'HeaderHash'.
newtype RbHash = MkRbHash {RbHash -> ByteString
rbHashBytes :: ByteString}
  deriving newtype (RbHash -> RbHash -> Bool
(RbHash -> RbHash -> Bool)
-> (RbHash -> RbHash -> Bool) -> Eq RbHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RbHash -> RbHash -> Bool
== :: RbHash -> RbHash -> Bool
$c/= :: RbHash -> RbHash -> Bool
/= :: RbHash -> RbHash -> Bool
Eq, Eq RbHash
Eq RbHash =>
(RbHash -> RbHash -> Ordering)
-> (RbHash -> RbHash -> Bool)
-> (RbHash -> RbHash -> Bool)
-> (RbHash -> RbHash -> Bool)
-> (RbHash -> RbHash -> Bool)
-> (RbHash -> RbHash -> RbHash)
-> (RbHash -> RbHash -> RbHash)
-> Ord RbHash
RbHash -> RbHash -> Bool
RbHash -> RbHash -> Ordering
RbHash -> RbHash -> RbHash
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: RbHash -> RbHash -> Ordering
compare :: RbHash -> RbHash -> Ordering
$c< :: RbHash -> RbHash -> Bool
< :: RbHash -> RbHash -> Bool
$c<= :: RbHash -> RbHash -> Bool
<= :: RbHash -> RbHash -> Bool
$c> :: RbHash -> RbHash -> Bool
> :: RbHash -> RbHash -> Bool
$c>= :: RbHash -> RbHash -> Bool
>= :: RbHash -> RbHash -> Bool
$cmax :: RbHash -> RbHash -> RbHash
max :: RbHash -> RbHash -> RbHash
$cmin :: RbHash -> RbHash -> RbHash
min :: RbHash -> RbHash -> RbHash
Ord, Context -> RbHash -> IO (Maybe ThunkInfo)
Proxy RbHash -> String
(Context -> RbHash -> IO (Maybe ThunkInfo))
-> (Context -> RbHash -> IO (Maybe ThunkInfo))
-> (Proxy RbHash -> String)
-> NoThunks RbHash
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> RbHash -> IO (Maybe ThunkInfo)
noThunks :: Context -> RbHash -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> RbHash -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> RbHash -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy RbHash -> String
showTypeOf :: Proxy RbHash -> String
NoThunks)
  deriving stock (forall x. RbHash -> Rep RbHash x)
-> (forall x. Rep RbHash x -> RbHash) -> Generic RbHash
forall x. Rep RbHash x -> RbHash
forall x. RbHash -> Rep RbHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. RbHash -> Rep RbHash x
from :: forall x. RbHash -> Rep RbHash x
$cto :: forall x. Rep RbHash x -> RbHash
to :: forall x. Rep RbHash x -> RbHash
Generic

instance Show RbHash where
  show :: RbHash -> String
show = RbHash -> String
prettyRbHash

encodeRbHash :: RbHash -> Encoding
encodeRbHash :: RbHash -> Encoding
encodeRbHash (MkRbHash ByteString
bytes) = ByteString -> Encoding
CBOR.encodeBytes ByteString
bytes

decodeRbHash :: Decoder s RbHash
decodeRbHash :: forall s. Decoder s RbHash
decodeRbHash = ByteString -> RbHash
MkRbHash (ByteString -> RbHash) -> Decoder s ByteString -> Decoder s RbHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s ByteString
forall s. Decoder s ByteString
CBOR.decodeBytes

prettyRbHash :: RbHash -> String
prettyRbHash :: RbHash -> String
prettyRbHash (MkRbHash ByteString
bytes) = ByteString -> String
BS8.unpack (ByteString -> ByteString
BS16.encode ByteString
bytes)

instance SignableRepresentation RbHash where
  getSignableRepresentation :: RbHash -> ByteString
getSignableRepresentation RbHash
point =
    Encoding -> ByteString
toStrictByteString (Encoding -> ByteString) -> Encoding -> ByteString
forall a b. (a -> b) -> a -> b
$
      RbHash -> Encoding
encodeRbHash RbHash
point

-- | Hash of a Leios transaction (the Blake2b-256 hash of its bytes).
newtype TxHash = MkTxHash ByteString
  deriving stock (TxHash -> TxHash -> Bool
(TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool) -> Eq TxHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxHash -> TxHash -> Bool
== :: TxHash -> TxHash -> Bool
$c/= :: TxHash -> TxHash -> Bool
/= :: TxHash -> TxHash -> Bool
Eq, Eq TxHash
Eq TxHash =>
(TxHash -> TxHash -> Ordering)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> TxHash)
-> (TxHash -> TxHash -> TxHash)
-> Ord TxHash
TxHash -> TxHash -> Bool
TxHash -> TxHash -> Ordering
TxHash -> TxHash -> TxHash
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: TxHash -> TxHash -> Ordering
compare :: TxHash -> TxHash -> Ordering
$c< :: TxHash -> TxHash -> Bool
< :: TxHash -> TxHash -> Bool
$c<= :: TxHash -> TxHash -> Bool
<= :: TxHash -> TxHash -> Bool
$c> :: TxHash -> TxHash -> Bool
> :: TxHash -> TxHash -> Bool
$c>= :: TxHash -> TxHash -> Bool
>= :: TxHash -> TxHash -> Bool
$cmax :: TxHash -> TxHash -> TxHash
max :: TxHash -> TxHash -> TxHash
$cmin :: TxHash -> TxHash -> TxHash
min :: TxHash -> TxHash -> TxHash
Ord, (forall x. TxHash -> Rep TxHash x)
-> (forall x. Rep TxHash x -> TxHash) -> Generic TxHash
forall x. Rep TxHash x -> TxHash
forall x. TxHash -> Rep TxHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TxHash -> Rep TxHash x
from :: forall x. TxHash -> Rep TxHash x
$cto :: forall x. Rep TxHash x -> TxHash
to :: forall x. Rep TxHash x -> TxHash
Generic)
  deriving anyclass (TxHash -> ()
(TxHash -> ()) -> NFData TxHash
forall a. (a -> ()) -> NFData a
$crnf :: TxHash -> ()
rnf :: TxHash -> ()
NFData, Context -> TxHash -> IO (Maybe ThunkInfo)
Proxy TxHash -> String
(Context -> TxHash -> IO (Maybe ThunkInfo))
-> (Context -> TxHash -> IO (Maybe ThunkInfo))
-> (Proxy TxHash -> String)
-> NoThunks TxHash
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> TxHash -> IO (Maybe ThunkInfo)
noThunks :: Context -> TxHash -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> TxHash -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> TxHash -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy TxHash -> String
showTypeOf :: Proxy TxHash -> String
NoThunks)

instance Show TxHash where
  show :: TxHash -> String
show = TxHash -> String
prettyTxHash

prettyTxHash :: TxHash -> String
prettyTxHash :: TxHash -> String
prettyTxHash (MkTxHash ByteString
bytes) = ByteString -> String
BS8.unpack (ByteString -> ByteString
BS16.encode ByteString
bytes)

-- * Points

-- | Uniquely identifies an endorser block in Leios. Could use 'Block SlotNo
-- EbHash' eventually, but a dedicated type is better to explore.
data LeiosPoint = MkLeiosPoint {LeiosPoint -> SlotNo
pointSlotNo :: SlotNo, LeiosPoint -> EbHash
pointEbHash :: EbHash}
  deriving stock (LeiosPoint -> LeiosPoint -> Bool
(LeiosPoint -> LeiosPoint -> Bool)
-> (LeiosPoint -> LeiosPoint -> Bool) -> Eq LeiosPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LeiosPoint -> LeiosPoint -> Bool
== :: LeiosPoint -> LeiosPoint -> Bool
$c/= :: LeiosPoint -> LeiosPoint -> Bool
/= :: LeiosPoint -> LeiosPoint -> Bool
Eq, Eq LeiosPoint
Eq LeiosPoint =>
(LeiosPoint -> LeiosPoint -> Ordering)
-> (LeiosPoint -> LeiosPoint -> Bool)
-> (LeiosPoint -> LeiosPoint -> Bool)
-> (LeiosPoint -> LeiosPoint -> Bool)
-> (LeiosPoint -> LeiosPoint -> Bool)
-> (LeiosPoint -> LeiosPoint -> LeiosPoint)
-> (LeiosPoint -> LeiosPoint -> LeiosPoint)
-> Ord LeiosPoint
LeiosPoint -> LeiosPoint -> Bool
LeiosPoint -> LeiosPoint -> Ordering
LeiosPoint -> LeiosPoint -> LeiosPoint
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LeiosPoint -> LeiosPoint -> Ordering
compare :: LeiosPoint -> LeiosPoint -> Ordering
$c< :: LeiosPoint -> LeiosPoint -> Bool
< :: LeiosPoint -> LeiosPoint -> Bool
$c<= :: LeiosPoint -> LeiosPoint -> Bool
<= :: LeiosPoint -> LeiosPoint -> Bool
$c> :: LeiosPoint -> LeiosPoint -> Bool
> :: LeiosPoint -> LeiosPoint -> Bool
$c>= :: LeiosPoint -> LeiosPoint -> Bool
>= :: LeiosPoint -> LeiosPoint -> Bool
$cmax :: LeiosPoint -> LeiosPoint -> LeiosPoint
max :: LeiosPoint -> LeiosPoint -> LeiosPoint
$cmin :: LeiosPoint -> LeiosPoint -> LeiosPoint
min :: LeiosPoint -> LeiosPoint -> LeiosPoint
Ord, (forall x. LeiosPoint -> Rep LeiosPoint x)
-> (forall x. Rep LeiosPoint x -> LeiosPoint) -> Generic LeiosPoint
forall x. Rep LeiosPoint x -> LeiosPoint
forall x. LeiosPoint -> Rep LeiosPoint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LeiosPoint -> Rep LeiosPoint x
from :: forall x. LeiosPoint -> Rep LeiosPoint x
$cto :: forall x. Rep LeiosPoint x -> LeiosPoint
to :: forall x. Rep LeiosPoint x -> LeiosPoint
Generic)
  deriving anyclass Context -> LeiosPoint -> IO (Maybe ThunkInfo)
Proxy LeiosPoint -> String
(Context -> LeiosPoint -> IO (Maybe ThunkInfo))
-> (Context -> LeiosPoint -> IO (Maybe ThunkInfo))
-> (Proxy LeiosPoint -> String)
-> NoThunks LeiosPoint
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> LeiosPoint -> IO (Maybe ThunkInfo)
noThunks :: Context -> LeiosPoint -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> LeiosPoint -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> LeiosPoint -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy LeiosPoint -> String
showTypeOf :: Proxy LeiosPoint -> String
NoThunks

instance ShowProxy LeiosPoint where showProxy :: Proxy LeiosPoint -> String
showProxy Proxy LeiosPoint
_ = String
"LeiosPoint"

instance Show LeiosPoint where
  show :: LeiosPoint -> String
show = LeiosPoint -> String
prettyLeiosPoint

instance SignableRepresentation LeiosPoint where
  getSignableRepresentation :: LeiosPoint -> ByteString
getSignableRepresentation LeiosPoint
point =
    Encoding -> ByteString
toStrictByteString (Encoding -> ByteString) -> Encoding -> ByteString
forall a b. (a -> b) -> a -> b
$
      -- REVIEW: Flat concatenation expected as what is signed?
      SlotNo -> Encoding
forall a. Serialise a => a -> Encoding
encode (LeiosPoint -> SlotNo
pointSlotNo LeiosPoint
point)
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> EbHash -> Encoding
encodeEbHash (LeiosPoint -> EbHash
pointEbHash LeiosPoint
point)

encodeLeiosPoint :: LeiosPoint -> Encoding
encodeLeiosPoint :: LeiosPoint -> Encoding
encodeLeiosPoint (MkLeiosPoint SlotNo
ebSlot EbHash
ebHash) =
  Word -> Encoding
CBOR.encodeListLen Word
2
    Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> SlotNo -> Encoding
forall a. Serialise a => a -> Encoding
encode SlotNo
ebSlot
    Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> EbHash -> Encoding
encodeEbHash EbHash
ebHash

decodeLeiosPoint :: Decoder s LeiosPoint
decodeLeiosPoint :: forall s. Decoder s LeiosPoint
decodeLeiosPoint =
  Text
-> (LeiosPoint -> Int)
-> Decoder s LeiosPoint
-> Decoder s LeiosPoint
forall a s. Text -> (a -> Int) -> Decoder s a -> Decoder s a
decodeRecordNamed (String -> Text
T.pack String
"LeiosPoint") (Int -> LeiosPoint -> Int
forall a b. a -> b -> a
const Int
2) (Decoder s LeiosPoint -> Decoder s LeiosPoint)
-> Decoder s LeiosPoint -> Decoder s LeiosPoint
forall a b. (a -> b) -> a -> b
$
    SlotNo -> EbHash -> LeiosPoint
MkLeiosPoint (SlotNo -> EbHash -> LeiosPoint)
-> Decoder s SlotNo -> Decoder s (EbHash -> LeiosPoint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s SlotNo
forall s. Decoder s SlotNo
forall a s. Serialise a => Decoder s a
decode Decoder s (EbHash -> LeiosPoint)
-> Decoder s EbHash -> Decoder s LeiosPoint
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s EbHash
forall s. Decoder s EbHash
decodeEbHash

prettyLeiosPoint :: LeiosPoint -> String
prettyLeiosPoint :: LeiosPoint -> String
prettyLeiosPoint (MkLeiosPoint (SlotNo Word64
slotNo) (MkEbHash ByteString
bytes)) =
  String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
slotNo String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteString -> String
BS8.unpack (ByteString -> ByteString
BS16.encode ByteString
bytes) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"

-- * Elections

-- | A ranking block leadership election: a slot and the pool it elected.
--
-- This is unrelated to the 'Ouroboros.Consensus.Committee.Crypto.ElectionId'
-- type family, which identifies an election of a voting committee. We do not
-- anticipate a module using both.
--
-- The derived 'Ord' orders by slot first, which pruning relies on.
data ElectionId = ElectionId
  { ElectionId -> SlotNo
electionSlot :: !SlotNo
  , ElectionId -> KeyHash BlockIssuer
electionElectee :: !(KeyHash BlockIssuer)
  }
  deriving stock (ElectionId -> ElectionId -> Bool
(ElectionId -> ElectionId -> Bool)
-> (ElectionId -> ElectionId -> Bool) -> Eq ElectionId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ElectionId -> ElectionId -> Bool
== :: ElectionId -> ElectionId -> Bool
$c/= :: ElectionId -> ElectionId -> Bool
/= :: ElectionId -> ElectionId -> Bool
Eq, Eq ElectionId
Eq ElectionId =>
(ElectionId -> ElectionId -> Ordering)
-> (ElectionId -> ElectionId -> Bool)
-> (ElectionId -> ElectionId -> Bool)
-> (ElectionId -> ElectionId -> Bool)
-> (ElectionId -> ElectionId -> Bool)
-> (ElectionId -> ElectionId -> ElectionId)
-> (ElectionId -> ElectionId -> ElectionId)
-> Ord ElectionId
ElectionId -> ElectionId -> Bool
ElectionId -> ElectionId -> Ordering
ElectionId -> ElectionId -> ElectionId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ElectionId -> ElectionId -> Ordering
compare :: ElectionId -> ElectionId -> Ordering
$c< :: ElectionId -> ElectionId -> Bool
< :: ElectionId -> ElectionId -> Bool
$c<= :: ElectionId -> ElectionId -> Bool
<= :: ElectionId -> ElectionId -> Bool
$c> :: ElectionId -> ElectionId -> Bool
> :: ElectionId -> ElectionId -> Bool
$c>= :: ElectionId -> ElectionId -> Bool
>= :: ElectionId -> ElectionId -> Bool
$cmax :: ElectionId -> ElectionId -> ElectionId
max :: ElectionId -> ElectionId -> ElectionId
$cmin :: ElectionId -> ElectionId -> ElectionId
min :: ElectionId -> ElectionId -> ElectionId
Ord, Int -> ElectionId -> ShowS
[ElectionId] -> ShowS
ElectionId -> String
(Int -> ElectionId -> ShowS)
-> (ElectionId -> String)
-> ([ElectionId] -> ShowS)
-> Show ElectionId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ElectionId -> ShowS
showsPrec :: Int -> ElectionId -> ShowS
$cshow :: ElectionId -> String
show :: ElectionId -> String
$cshowList :: [ElectionId] -> ShowS
showList :: [ElectionId] -> ShowS
Show, (forall x. ElectionId -> Rep ElectionId x)
-> (forall x. Rep ElectionId x -> ElectionId) -> Generic ElectionId
forall x. Rep ElectionId x -> ElectionId
forall x. ElectionId -> Rep ElectionId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ElectionId -> Rep ElectionId x
from :: forall x. ElectionId -> Rep ElectionId x
$cto :: forall x. Rep ElectionId x -> ElectionId
to :: forall x. Rep ElectionId x -> ElectionId
Generic)
  deriving anyclass Context -> ElectionId -> IO (Maybe ThunkInfo)
Proxy ElectionId -> String
(Context -> ElectionId -> IO (Maybe ThunkInfo))
-> (Context -> ElectionId -> IO (Maybe ThunkInfo))
-> (Proxy ElectionId -> String)
-> NoThunks ElectionId
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> ElectionId -> IO (Maybe ThunkInfo)
noThunks :: Context -> ElectionId -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> ElectionId -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> ElectionId -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy ElectionId -> String
showTypeOf :: Proxy ElectionId -> String
NoThunks

-- * Votes

-- | A vote for a Leios announcement.
data LeiosVote = MkLeiosVote
  { LeiosVote -> RbHash
voteAnnouncingRbHash :: !RbHash
  -- ^ the 'HeaderHash' of the ranking block ('s header) that carries the
  -- announcement
  , LeiosVote -> LeiosSeatId
voteSeatId :: !LeiosSeatId
  -- ^ the voter's seat in the committee
  , LeiosVote -> SigDSIGN LeiosDSIGN
voteSignature :: !LeiosSignature
  -- ^ the voter's signature of 'voteAnnouncingRbHash'
  }
  deriving stock (LeiosVote -> LeiosVote -> Bool
(LeiosVote -> LeiosVote -> Bool)
-> (LeiosVote -> LeiosVote -> Bool) -> Eq LeiosVote
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LeiosVote -> LeiosVote -> Bool
== :: LeiosVote -> LeiosVote -> Bool
$c/= :: LeiosVote -> LeiosVote -> Bool
/= :: LeiosVote -> LeiosVote -> Bool
Eq, Int -> LeiosVote -> ShowS
[LeiosVote] -> ShowS
LeiosVote -> String
(Int -> LeiosVote -> ShowS)
-> (LeiosVote -> String)
-> ([LeiosVote] -> ShowS)
-> Show LeiosVote
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LeiosVote -> ShowS
showsPrec :: Int -> LeiosVote -> ShowS
$cshow :: LeiosVote -> String
show :: LeiosVote -> String
$cshowList :: [LeiosVote] -> ShowS
showList :: [LeiosVote] -> ShowS
Show, (forall x. LeiosVote -> Rep LeiosVote x)
-> (forall x. Rep LeiosVote x -> LeiosVote) -> Generic LeiosVote
forall x. Rep LeiosVote x -> LeiosVote
forall x. LeiosVote -> Rep LeiosVote x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LeiosVote -> Rep LeiosVote x
from :: forall x. LeiosVote -> Rep LeiosVote x
$cto :: forall x. Rep LeiosVote x -> LeiosVote
to :: forall x. Rep LeiosVote x -> LeiosVote
Generic)
  deriving anyclass Context -> LeiosVote -> IO (Maybe ThunkInfo)
Proxy LeiosVote -> String
(Context -> LeiosVote -> IO (Maybe ThunkInfo))
-> (Context -> LeiosVote -> IO (Maybe ThunkInfo))
-> (Proxy LeiosVote -> String)
-> NoThunks LeiosVote
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> LeiosVote -> IO (Maybe ThunkInfo)
noThunks :: Context -> LeiosVote -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> LeiosVote -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> LeiosVote -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy LeiosVote -> String
showTypeOf :: Proxy LeiosVote -> String
NoThunks

instance ShowProxy LeiosVote where showProxy :: Proxy LeiosVote -> String
showProxy Proxy LeiosVote
_ = String
"LeiosVote"

encodeLeiosVote :: LeiosVote -> Encoding
encodeLeiosVote :: LeiosVote -> Encoding
encodeLeiosVote (MkLeiosVote RbHash
rbHash LeiosSeatId
seat SigDSIGN LeiosDSIGN
signature) =
  Word -> Encoding
CBOR.encodeListLen Word
3
    Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> RbHash -> Encoding
encodeRbHash RbHash
rbHash
    Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word16 -> Encoding
CBOR.encodeWord16 (LeiosSeatId -> Word16
leiosSeatIndex LeiosSeatId
seat)
    Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> SigDSIGN LeiosDSIGN -> Encoding
forall a. FixedSizeCodec a => a -> Encoding
encodeFixedSized SigDSIGN LeiosDSIGN
signature

decodeLeiosVote :: Decoder s LeiosVote
decodeLeiosVote :: forall s. Decoder s LeiosVote
decodeLeiosVote =
  Text
-> (LeiosVote -> Int) -> Decoder s LeiosVote -> Decoder s LeiosVote
forall a s. Text -> (a -> Int) -> Decoder s a -> Decoder s a
decodeRecordNamed (String -> Text
T.pack String
"LeiosVote") (Int -> LeiosVote -> Int
forall a b. a -> b -> a
const Int
3) (Decoder s LeiosVote -> Decoder s LeiosVote)
-> Decoder s LeiosVote -> Decoder s LeiosVote
forall a b. (a -> b) -> a -> b
$
    RbHash -> LeiosSeatId -> SigDSIGN LeiosDSIGN -> LeiosVote
MkLeiosVote (RbHash -> LeiosSeatId -> SigDSIGN LeiosDSIGN -> LeiosVote)
-> Decoder s RbHash
-> Decoder s (LeiosSeatId -> SigDSIGN LeiosDSIGN -> LeiosVote)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s RbHash
forall s. Decoder s RbHash
decodeRbHash Decoder s (LeiosSeatId -> SigDSIGN LeiosDSIGN -> LeiosVote)
-> Decoder s LeiosSeatId
-> Decoder s (SigDSIGN LeiosDSIGN -> LeiosVote)
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> LeiosSeatId
LeiosSeatId (Word16 -> LeiosSeatId)
-> Decoder s Word16 -> Decoder s LeiosSeatId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Word16
forall s. Decoder s Word16
CBOR.decodeWord16) Decoder s (SigDSIGN LeiosDSIGN -> LeiosVote)
-> Decoder s (SigDSIGN LeiosDSIGN) -> Decoder s LeiosVote
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s (SigDSIGN LeiosDSIGN)
forall a s. FixedSizeCodec a => Decoder s a
decodeFixedSized

-- * Endorser blocks

type BytesSize = Word32

-- | An Endorser Block as it is submitted through the network.
-- TODO: Keep track of the slot of an EB?
data LeiosEb = MkLeiosEb
  { LeiosEb -> Vector (TxHash, Word32)
leiosEbTxs :: !(Vector (TxHash, BytesSize))
  }
  deriving stock (Int -> LeiosEb -> ShowS
[LeiosEb] -> ShowS
LeiosEb -> String
(Int -> LeiosEb -> ShowS)
-> (LeiosEb -> String) -> ([LeiosEb] -> ShowS) -> Show LeiosEb
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LeiosEb -> ShowS
showsPrec :: Int -> LeiosEb -> ShowS
$cshow :: LeiosEb -> String
show :: LeiosEb -> String
$cshowList :: [LeiosEb] -> ShowS
showList :: [LeiosEb] -> ShowS
Show, LeiosEb -> LeiosEb -> Bool
(LeiosEb -> LeiosEb -> Bool)
-> (LeiosEb -> LeiosEb -> Bool) -> Eq LeiosEb
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LeiosEb -> LeiosEb -> Bool
== :: LeiosEb -> LeiosEb -> Bool
$c/= :: LeiosEb -> LeiosEb -> Bool
/= :: LeiosEb -> LeiosEb -> Bool
Eq, (forall x. LeiosEb -> Rep LeiosEb x)
-> (forall x. Rep LeiosEb x -> LeiosEb) -> Generic LeiosEb
forall x. Rep LeiosEb x -> LeiosEb
forall x. LeiosEb -> Rep LeiosEb x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LeiosEb -> Rep LeiosEb x
from :: forall x. LeiosEb -> Rep LeiosEb x
$cto :: forall x. Rep LeiosEb x -> LeiosEb
to :: forall x. Rep LeiosEb x -> LeiosEb
Generic)
  deriving anyclass Context -> LeiosEb -> IO (Maybe ThunkInfo)
Proxy LeiosEb -> String
(Context -> LeiosEb -> IO (Maybe ThunkInfo))
-> (Context -> LeiosEb -> IO (Maybe ThunkInfo))
-> (Proxy LeiosEb -> String)
-> NoThunks LeiosEb
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> LeiosEb -> IO (Maybe ThunkInfo)
noThunks :: Context -> LeiosEb -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> LeiosEb -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> LeiosEb -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy LeiosEb -> String
showTypeOf :: Proxy LeiosEb -> String
NoThunks

instance ShowProxy LeiosEb where showProxy :: Proxy LeiosEb -> String
showProxy Proxy LeiosEb
_ = String
"LeiosEb"

leiosEbBodyItems :: LeiosEb -> [(Int, TxHash, BytesSize)]
leiosEbBodyItems :: LeiosEb -> [(Int, TxHash, Word32)]
leiosEbBodyItems LeiosEb
eb =
  LeiosEb -> Vector (TxHash, Word32)
leiosEbTxs LeiosEb
eb
    Vector (TxHash, Word32)
-> (Vector (TxHash, Word32) -> Vector (Int, TxHash, Word32))
-> Vector (Int, TxHash, Word32)
forall a b. a -> (a -> b) -> b
& (Int -> (TxHash, Word32) -> (Int, TxHash, Word32))
-> Vector (TxHash, Word32) -> Vector (Int, TxHash, Word32)
forall a b. (Int -> a -> b) -> Vector a -> Vector b
V.imap (\Int
ix (TxHash
txh, Word32
size) -> (Int
ix, TxHash
txh, Word32
size))
    Vector (Int, TxHash, Word32)
-> (Vector (Int, TxHash, Word32) -> [(Int, TxHash, Word32)])
-> [(Int, TxHash, Word32)]
forall a b. a -> (a -> b) -> b
& Vector (Int, TxHash, Word32) -> [(Int, TxHash, Word32)]
forall a. Vector a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

-- | The bytes one reference occupies for a transaction of the given size: the
-- hash and the size itself, exactly as the EB's CBOR encoding writes them.
--
-- Also used on the Dijkstra transaction measure, so the mempool charges a
-- transaction what it will actually cost in the reference list rather than an
-- approximation of it.
encodeLeiosEbItemSize :: ByteSize32 -> ByteSize32
encodeLeiosEbItemSize :: ByteSize32 -> ByteSize32
encodeLeiosEbItemSize (ByteSize32 Word32
txSize) =
  Word32 -> ByteSize32
ByteSize32 (Word32 -> ByteSize32) -> Word32 -> ByteSize32
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32
cborBytesSize Word32
32 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32 -> Word32
forall i. Integral i => i -> Word32
cborIntBytesSize Word32
txSize
 where
  cborBytesSize :: Word32 -> Word32
cborBytesSize Word32
len = Word32 -> Word32
forall i. Integral i => i -> Word32
cborIntBytesSize Word32
len Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
len

-- | Encode a 'LeiosEb' as a CBOR map from each transaction hash to the size
-- of that transaction. Must not add more overhead than
-- 'encodeLeiosEbMaxFramingSize', and the encoding of each reference must match
-- 'encodeLeiosEbItemSize'.
--
-- The mempool charges each transaction 'encodeLeiosEbItemSize', and the
-- endorser-block capacity subtracts 'encodeLeiosEbMaxFramingSize'. If the
-- encoding changes, both sizes must change with it.
--
-- Endorser blocks are on chain, so peers on every node-to-node version must
-- write the same bytes. This encoding has no version yet. When an era after
-- Dijkstra changes it, the @ProtVer@ of that era will select the encoding.
encodeLeiosEb :: LeiosEb -> Encoding
encodeLeiosEb :: LeiosEb -> Encoding
encodeLeiosEb (MkLeiosEb Vector (TxHash, Word32)
references) =
  (Encoding -> (TxHash, Word32) -> Encoding)
-> Encoding -> Vector (TxHash, Word32) -> Encoding
forall b a. (b -> a -> b) -> b -> Vector a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
    ( \Encoding
acc (MkTxHash ByteString
bytes, Word32
txBytesSize) ->
        Encoding
acc Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
CBOR.encodeBytes ByteString
bytes Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word32 -> Encoding
CBOR.encodeWord32 Word32
txBytesSize
    )
    (Word -> Encoding
CBOR.encodeMapLen (Word -> Encoding) -> Word -> Encoding
forall a b. (a -> b) -> a -> b
$ Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ Vector (TxHash, Word32) -> Int
forall a. Vector a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector (TxHash, Word32)
references)
    Vector (TxHash, Word32)
references

-- | The widest the framing 'encodeLeiosEb' writes around the references can
-- get: the map header. CBOR map headers have the same widths as
-- 'cborIntBytesSize', and the reference count fits 'BytesSize'.
--
-- A capacity expressed in references ('encodeLeiosEbItemSize' each)
-- subtracts this once at the block level; no single transaction can be
-- charged for it.
encodeLeiosEbMaxFramingSize :: ByteSize32
encodeLeiosEbMaxFramingSize :: ByteSize32
encodeLeiosEbMaxFramingSize = Word32 -> ByteSize32
ByteSize32 (Word32 -> ByteSize32) -> Word32 -> ByteSize32
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32
forall i. Integral i => i -> Word32
cborIntBytesSize (Word32
forall a. Bounded a => a
maxBound :: BytesSize)

-- | The references capacity a @maxEndorserBlockReferencesSize@ parameter
-- yields: the parameter minus the framing 'encodeLeiosEb' writes ahead of the
-- references. A parameter smaller than the framing exhausts the capacity, so
-- no reference fits, rather than wrapping around to \"no limit\".
leiosReferencesCapacity :: BytesSize -> BytesSize
leiosReferencesCapacity :: Word32 -> Word32
leiosReferencesCapacity Word32
paramLimit = Word32
paramLimit Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32 -> Word32 -> Word32
forall a. Ord a => a -> a -> a
min Word32
paramLimit Word32
framing
 where
  ByteSize32 Word32
framing = ByteSize32
encodeLeiosEbMaxFramingSize

-- | Compute the size of a 'LeiosEb' in its CBOR encoding.
encodeLeiosEbSize :: LeiosEb -> BytesSize
encodeLeiosEbSize :: LeiosEb -> Word32
encodeLeiosEbSize (MkLeiosEb Vector (TxHash, Word32)
items) =
  Int -> Word32
forall i. Integral i => i -> Word32
cborIntBytesSize (Vector (TxHash, Word32) -> Int
forall a. Vector a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector (TxHash, Word32)
items)
    Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Vector Word32 -> Word32
forall a. Num a => Vector a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (((TxHash, Word32) -> Word32)
-> Vector (TxHash, Word32) -> Vector Word32
forall a b. (a -> b) -> Vector a -> Vector b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteSize32 -> Word32
unByteSize32 (ByteSize32 -> Word32)
-> ((TxHash, Word32) -> ByteSize32) -> (TxHash, Word32) -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteSize32 -> ByteSize32
encodeLeiosEbItemSize (ByteSize32 -> ByteSize32)
-> ((TxHash, Word32) -> ByteSize32)
-> (TxHash, Word32)
-> ByteSize32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> ByteSize32
ByteSize32 (Word32 -> ByteSize32)
-> ((TxHash, Word32) -> Word32) -> (TxHash, Word32) -> ByteSize32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TxHash, Word32) -> Word32
forall a b. (a, b) -> b
snd) Vector (TxHash, Word32)
items)

-- | Length of a unsigned integer if it were encoded in a "flattened format".
-- See 'encodeInteger'.
cborIntBytesSize :: Integral i => i -> BytesSize
cborIntBytesSize :: forall i. Integral i => i -> Word32
cborIntBytesSize i
n
  | i
n i -> i -> Bool
forall a. Ord a => a -> a -> Bool
< i
24 = Word32
1
  | i
n i -> i -> Bool
forall a. Ord a => a -> a -> Bool
< i
0x100 = Word32
2
  | i
n i -> i -> Bool
forall a. Ord a => a -> a -> Bool
< i
0x10000 = Word32
3
  | Bool
otherwise = Word32
5

-- * Header checks

-- | A duration the ledger gives in milliseconds.
milliseconds32ToNominalDiffTime :: Milliseconds32 -> NominalDiffTime
milliseconds32ToNominalDiffTime :: Milliseconds32 -> NominalDiffTime
milliseconds32ToNominalDiffTime (Milliseconds32 Word32
ms) = Word32 -> NominalDiffTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ms NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Fractional a => a -> a -> a
/ NominalDiffTime
1000

-- | The earliest slot at which a block may certify an endorser block announced
-- in the given slot.
--
-- The announcement, voting and diffusion periods must all have elapsed. They
-- are wall-clock durations, so the gap rounds up to whole slots: a block is
-- forged at its slot's onset, so the answer is the first slot whose onset is far
-- enough after the announcement.
minCertificationSlot ::
  SlotLength ->
  -- | Announcement period length
  Milliseconds32 ->
  -- | Vote period length
  Milliseconds32 ->
  -- | Diffusion period length
  Milliseconds32 ->
  -- | Slot of the announcing block
  SlotNo ->
  SlotNo
minCertificationSlot :: SlotLength
-> Milliseconds32
-> Milliseconds32
-> Milliseconds32
-> SlotNo
-> SlotNo
minCertificationSlot SlotLength
slotLength Milliseconds32
announcement Milliseconds32
vote Milliseconds32
diffusion SlotNo
announcingSlot =
  SlotNo
announcingSlot SlotNo -> SlotNo -> SlotNo
forall a. Num a => a -> a -> a
+ Word64 -> SlotNo
SlotNo (Integer -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Integer
totalMs Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
slotMs Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
slotMs))
 where
  totalMs :: Integer
totalMs = Integer
3 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Milliseconds32 -> Integer
ms Milliseconds32
announcement Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Milliseconds32 -> Integer
ms Milliseconds32
vote Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Milliseconds32 -> Integer
ms Milliseconds32
diffusion
  ms :: Milliseconds32 -> Integer
ms = Word32 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word32 -> Integer)
-> (Milliseconds32 -> Word32) -> Milliseconds32 -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Milliseconds32 -> Word32
unMilliseconds32
  slotMs :: Integer
slotMs = case SlotLength -> Integer
slotLengthToMillisec SlotLength
slotLength of
    Integer
0 -> String -> Integer
forall a. HasCallStack => String -> a
error String
"minCertificationSlot: zero slot length"
    Integer
n -> Integer
n