{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Cardano.Ledger.State.Leios (
LeiosCommittee (..),
LeiosSeat (..),
emptyLeiosCommittee,
LeiosCandidate (..),
selectLeiosCommittee,
leiosCommitteeToJSON,
EbAnnouncement (..),
) where
import Cardano.Crypto.Leios (LeiosCommittee (..), LeiosSeat (..), Weight, mkLeiosCommittee)
import Cardano.Ledger.BaseTypes (
EpochInterval,
KeyValuePairs (..),
StrictMaybe (..),
ToKeyValuePairs (..),
addEpochInterval,
strictMaybeToMaybe,
)
import Cardano.Ledger.Binary (DecCBOR (..), EncCBOR (..), decodeRecordNamed, encodeListLen)
import Cardano.Ledger.Block (EbReferencesAnnouncement)
import Cardano.Ledger.Coin (Coin, CompactForm)
import Cardano.Ledger.Hashes (EraIndependentBlockHeader, SafeHash)
import Cardano.Ledger.Keys (KeyHash, StakePool)
import Cardano.Ledger.Slot (EpochNo, SlotNo)
import Cardano.Ledger.State.StakePool (BlsKey (..), BlsKeyState (..))
import Control.DeepSeq (NFData)
import Data.Aeson (ToJSON (..), Value, object, toJSON, (.=))
import Data.Function ((&))
import Data.Ord (Down (..))
import Data.Vector (Vector)
import qualified Data.Vector as V
import qualified Data.Vector.Algorithms.Intro as Intro
import qualified Data.Vector.Strict as VS
import Data.Word (Word16)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)
emptyLeiosCommittee :: LeiosCommittee
emptyLeiosCommittee :: LeiosCommittee
emptyLeiosCommittee = Vector LeiosSeat -> LeiosCommittee
UnsafeLeiosCommittee Vector LeiosSeat
forall a. Vector a
VS.empty
data LeiosCandidate = LeiosCandidate
{ LeiosCandidate -> KeyHash StakePool
lcPoolId :: !(KeyHash StakePool)
, LeiosCandidate -> CompactForm Coin
lcStake :: !(CompactForm Coin)
, LeiosCandidate -> Weight
lcWeight :: !Weight
, LeiosCandidate -> StrictMaybe BlsKeyState
lcKey :: !(StrictMaybe BlsKeyState)
}
deriving (Int -> LeiosCandidate -> ShowS
[LeiosCandidate] -> ShowS
LeiosCandidate -> String
(Int -> LeiosCandidate -> ShowS)
-> (LeiosCandidate -> String)
-> ([LeiosCandidate] -> ShowS)
-> Show LeiosCandidate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LeiosCandidate -> ShowS
showsPrec :: Int -> LeiosCandidate -> ShowS
$cshow :: LeiosCandidate -> String
show :: LeiosCandidate -> String
$cshowList :: [LeiosCandidate] -> ShowS
showList :: [LeiosCandidate] -> ShowS
Show, LeiosCandidate -> LeiosCandidate -> Bool
(LeiosCandidate -> LeiosCandidate -> Bool)
-> (LeiosCandidate -> LeiosCandidate -> Bool) -> Eq LeiosCandidate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LeiosCandidate -> LeiosCandidate -> Bool
== :: LeiosCandidate -> LeiosCandidate -> Bool
$c/= :: LeiosCandidate -> LeiosCandidate -> Bool
/= :: LeiosCandidate -> LeiosCandidate -> Bool
Eq)
selectLeiosCommittee ::
EpochNo -> EpochInterval -> Word16 -> Vector LeiosCandidate -> LeiosCommittee
selectLeiosCommittee :: EpochNo
-> EpochInterval
-> Word16
-> Vector LeiosCandidate
-> LeiosCommittee
selectLeiosCommittee EpochNo
_ EpochInterval
_ Word16
0 Vector LeiosCandidate
_ = LeiosCommittee
emptyLeiosCommittee
selectLeiosCommittee EpochNo
epochNo EpochInterval
maxKeyAge Word16
committeeSize Vector LeiosCandidate
candidates =
Vector LeiosCandidate
candidates
Vector LeiosCandidate
-> (Vector LeiosCandidate -> Vector LeiosCandidate)
-> Vector LeiosCandidate
forall a b. a -> (a -> b) -> b
& Vector LeiosCandidate -> Vector LeiosCandidate
sortByStake
Vector LeiosCandidate
-> (Vector LeiosCandidate -> Vector LeiosCandidate)
-> Vector LeiosCandidate
forall a b. a -> (a -> b) -> b
& Int -> Vector LeiosCandidate -> Vector LeiosCandidate
forall a. Int -> Vector a -> Vector a
V.take Int
size
Vector LeiosCandidate
-> (Vector LeiosCandidate
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight))
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
forall a b. a -> (a -> b) -> b
& (LeiosCandidate
-> (StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight))
-> Vector LeiosCandidate
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
forall a b. (a -> b) -> Vector a -> Vector b
V.map LeiosCandidate
-> (StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
toSeat
Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> (Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight))
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
forall a b. a -> (a -> b) -> b
& Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert
Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> (Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> LeiosCommittee)
-> LeiosCommittee
forall a b. a -> (a -> b) -> b
& Vector
(StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
-> LeiosCommittee
mkLeiosCommittee
where
sortByStake :: Vector LeiosCandidate -> Vector LeiosCandidate
sortByStake = (forall s. MVector s LeiosCandidate -> ST s ())
-> Vector LeiosCandidate -> Vector LeiosCandidate
forall a.
(forall s. MVector s a -> ST s ()) -> Vector a -> Vector a
V.modify (\MVector s LeiosCandidate
mv -> Comparison LeiosCandidate
-> MVector (PrimState (ST s)) LeiosCandidate -> Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> Int -> m ()
Intro.partialSortBy Comparison LeiosCandidate
higherStake MVector s LeiosCandidate
MVector (PrimState (ST s)) LeiosCandidate
mv Int
size)
size :: Int
size = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Int Word16
committeeSize) (Vector LeiosCandidate -> Int
forall a. Vector a -> Int
V.length Vector LeiosCandidate
candidates)
higherStake :: Comparison LeiosCandidate
higherStake LeiosCandidate
a LeiosCandidate
b =
(Down (CompactForm Coin), KeyHash StakePool)
-> (Down (CompactForm Coin), KeyHash StakePool) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (CompactForm Coin -> Down (CompactForm Coin)
forall a. a -> Down a
Down (LeiosCandidate -> CompactForm Coin
lcStake LeiosCandidate
a), LeiosCandidate -> KeyHash StakePool
lcPoolId LeiosCandidate
a) (CompactForm Coin -> Down (CompactForm Coin)
forall a. a -> Down a
Down (LeiosCandidate -> CompactForm Coin
lcStake LeiosCandidate
b), LeiosCandidate -> KeyHash StakePool
lcPoolId LeiosCandidate
b)
toSeat :: LeiosCandidate
-> (StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN),
Weight)
toSeat LeiosCandidate
c = (LeiosCandidate
-> StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN)
honouredKey LeiosCandidate
c, LeiosCandidate -> Weight
lcWeight LeiosCandidate
c)
honouredKey :: LeiosCandidate
-> StrictMaybe
(VerKeyDSIGN BLS12381MinSigDSIGN,
PossessionProofDSIGN BLS12381MinSigDSIGN)
honouredKey LeiosCandidate
c = do
bks <- LeiosCandidate -> StrictMaybe BlsKeyState
lcKey LeiosCandidate
c
if epochNo < addEpochInterval (bksRegisteredIn bks) maxKeyAge
then let BlsKey vk pop = bksKey bks in SJust (vk, pop)
else SNothing
leiosCommitteeToJSON :: LeiosCommittee -> Value
leiosCommitteeToJSON :: LeiosCommittee -> Value
leiosCommitteeToJSON =
[Value] -> Value
forall a. ToJSON a => a -> Value
toJSON ([Value] -> Value)
-> (LeiosCommittee -> [Value]) -> LeiosCommittee -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LeiosSeat -> Value) -> [LeiosSeat] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map LeiosSeat -> Value
leiosSeatToJSON ([LeiosSeat] -> [Value])
-> (LeiosCommittee -> [LeiosSeat]) -> LeiosCommittee -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector LeiosSeat -> [LeiosSeat]
forall a. Vector a -> [a]
VS.toList (Vector LeiosSeat -> [LeiosSeat])
-> (LeiosCommittee -> Vector LeiosSeat)
-> LeiosCommittee
-> [LeiosSeat]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LeiosCommittee -> Vector LeiosSeat
leiosCommitteeSeats
where
leiosSeatToJSON :: LeiosSeat -> Value
leiosSeatToJSON (LeiosSeat Weight
weight StrictMaybe (VerKeyDSIGN BLS12381MinSigDSIGN)
vkey) =
[Pair] -> Value
object
[ Key
"seatWeight" Key -> Weight -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Weight
weight
, Key
"seatVKey" Key -> String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Maybe (VerKeyDSIGN BLS12381MinSigDSIGN) -> String
forall a. Show a => a -> String
show (StrictMaybe (VerKeyDSIGN BLS12381MinSigDSIGN)
-> Maybe (VerKeyDSIGN BLS12381MinSigDSIGN)
forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe (VerKeyDSIGN BLS12381MinSigDSIGN)
vkey)
]
data EbAnnouncement = EbAnnouncement
{ EbAnnouncement -> EbReferencesAnnouncement
ebAnnouncement :: !EbReferencesAnnouncement
, EbAnnouncement -> SlotNo
ebAnnouncementSlotNo :: !SlotNo
, :: !(SafeHash EraIndependentBlockHeader)
}
deriving stock (Int -> EbAnnouncement -> ShowS
[EbAnnouncement] -> ShowS
EbAnnouncement -> String
(Int -> EbAnnouncement -> ShowS)
-> (EbAnnouncement -> String)
-> ([EbAnnouncement] -> ShowS)
-> Show EbAnnouncement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EbAnnouncement -> ShowS
showsPrec :: Int -> EbAnnouncement -> ShowS
$cshow :: EbAnnouncement -> String
show :: EbAnnouncement -> String
$cshowList :: [EbAnnouncement] -> ShowS
showList :: [EbAnnouncement] -> ShowS
Show, EbAnnouncement -> EbAnnouncement -> Bool
(EbAnnouncement -> EbAnnouncement -> Bool)
-> (EbAnnouncement -> EbAnnouncement -> Bool) -> Eq EbAnnouncement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EbAnnouncement -> EbAnnouncement -> Bool
== :: EbAnnouncement -> EbAnnouncement -> Bool
$c/= :: EbAnnouncement -> EbAnnouncement -> Bool
/= :: EbAnnouncement -> EbAnnouncement -> Bool
Eq, (forall x. EbAnnouncement -> Rep EbAnnouncement x)
-> (forall x. Rep EbAnnouncement x -> EbAnnouncement)
-> Generic EbAnnouncement
forall x. Rep EbAnnouncement x -> EbAnnouncement
forall x. EbAnnouncement -> Rep EbAnnouncement x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EbAnnouncement -> Rep EbAnnouncement x
from :: forall x. EbAnnouncement -> Rep EbAnnouncement x
$cto :: forall x. Rep EbAnnouncement x -> EbAnnouncement
to :: forall x. Rep EbAnnouncement x -> EbAnnouncement
Generic)
deriving anyclass (Context -> EbAnnouncement -> IO (Maybe ThunkInfo)
Proxy EbAnnouncement -> String
(Context -> EbAnnouncement -> IO (Maybe ThunkInfo))
-> (Context -> EbAnnouncement -> IO (Maybe ThunkInfo))
-> (Proxy EbAnnouncement -> String)
-> NoThunks EbAnnouncement
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> EbAnnouncement -> IO (Maybe ThunkInfo)
noThunks :: Context -> EbAnnouncement -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> EbAnnouncement -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> EbAnnouncement -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy EbAnnouncement -> String
showTypeOf :: Proxy EbAnnouncement -> String
NoThunks, EbAnnouncement -> ()
(EbAnnouncement -> ()) -> NFData EbAnnouncement
forall a. (a -> ()) -> NFData a
$crnf :: EbAnnouncement -> ()
rnf :: EbAnnouncement -> ()
NFData)
deriving ([EbAnnouncement] -> Value
[EbAnnouncement] -> Encoding
EbAnnouncement -> Bool
EbAnnouncement -> Value
EbAnnouncement -> Encoding
(EbAnnouncement -> Value)
-> (EbAnnouncement -> Encoding)
-> ([EbAnnouncement] -> Value)
-> ([EbAnnouncement] -> Encoding)
-> (EbAnnouncement -> Bool)
-> ToJSON EbAnnouncement
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: EbAnnouncement -> Value
toJSON :: EbAnnouncement -> Value
$ctoEncoding :: EbAnnouncement -> Encoding
toEncoding :: EbAnnouncement -> Encoding
$ctoJSONList :: [EbAnnouncement] -> Value
toJSONList :: [EbAnnouncement] -> Value
$ctoEncodingList :: [EbAnnouncement] -> Encoding
toEncodingList :: [EbAnnouncement] -> Encoding
$comitField :: EbAnnouncement -> Bool
omitField :: EbAnnouncement -> Bool
ToJSON) via KeyValuePairs EbAnnouncement
instance EncCBOR EbAnnouncement where
encCBOR :: EbAnnouncement -> Encoding
encCBOR (EbAnnouncement EbReferencesAnnouncement
a SlotNo
s SafeHash EraIndependentBlockHeader
h) =
Word -> Encoding
encodeListLen Word
3
Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> EbReferencesAnnouncement -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR EbReferencesAnnouncement
a
Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> SlotNo -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR SlotNo
s
Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> SafeHash EraIndependentBlockHeader -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR SafeHash EraIndependentBlockHeader
h
instance DecCBOR EbAnnouncement where
decCBOR :: forall s. Decoder s EbAnnouncement
decCBOR =
Text
-> (EbAnnouncement -> Int)
-> Decoder s EbAnnouncement
-> Decoder s EbAnnouncement
forall a s. Text -> (a -> Int) -> Decoder s a -> Decoder s a
decodeRecordNamed Text
"EbAnnouncement" (Int -> EbAnnouncement -> Int
forall a b. a -> b -> a
const Int
3) (Decoder s EbAnnouncement -> Decoder s EbAnnouncement)
-> Decoder s EbAnnouncement -> Decoder s EbAnnouncement
forall a b. (a -> b) -> a -> b
$
EbReferencesAnnouncement
-> SlotNo -> SafeHash EraIndependentBlockHeader -> EbAnnouncement
EbAnnouncement
(EbReferencesAnnouncement
-> SlotNo -> SafeHash EraIndependentBlockHeader -> EbAnnouncement)
-> Decoder s EbReferencesAnnouncement
-> Decoder
s (SlotNo -> SafeHash EraIndependentBlockHeader -> EbAnnouncement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s EbReferencesAnnouncement
forall s. Decoder s EbReferencesAnnouncement
forall a s. DecCBOR a => Decoder s a
decCBOR
Decoder
s (SlotNo -> SafeHash EraIndependentBlockHeader -> EbAnnouncement)
-> Decoder s SlotNo
-> Decoder s (SafeHash EraIndependentBlockHeader -> EbAnnouncement)
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 SlotNo
forall s. Decoder s SlotNo
forall a s. DecCBOR a => Decoder s a
decCBOR
Decoder s (SafeHash EraIndependentBlockHeader -> EbAnnouncement)
-> Decoder s (SafeHash EraIndependentBlockHeader)
-> Decoder s EbAnnouncement
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 (SafeHash EraIndependentBlockHeader)
forall s. Decoder s (SafeHash EraIndependentBlockHeader)
forall a s. DecCBOR a => Decoder s a
decCBOR
instance ToKeyValuePairs EbAnnouncement where
toKeyValuePairs :: forall e kv. KeyValue e kv => EbAnnouncement -> [kv]
toKeyValuePairs (EbAnnouncement EbReferencesAnnouncement
a SlotNo
s SafeHash EraIndependentBlockHeader
h) =
[ Key
"announcement" Key -> EbReferencesAnnouncement -> kv
forall v. ToJSON v => Key -> v -> kv
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= EbReferencesAnnouncement
a
, Key
"slotNo" Key -> SlotNo -> kv
forall v. ToJSON v => Key -> v -> kv
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= SlotNo
s
, Key
"announcedInBlockHeader" Key -> SafeHash EraIndependentBlockHeader -> kv
forall v. ToJSON v => Key -> v -> kv
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= SafeHash EraIndependentBlockHeader
h
]