{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Ouroboros.Consensus.Protocol.Praos.Common (
MaxMajorProtVer (..)
, PraosCanBeLeader (..)
, PraosChainSelectView (..)
, VRFTiebreakerFlavor (..)
, PraosNonces (..)
, PraosProtocolSupportsNode (..)
) where
import qualified Cardano.Crypto.VRF as VRF
import Cardano.Ledger.BaseTypes (Nonce)
import qualified Cardano.Ledger.BaseTypes as SL
import Cardano.Ledger.Crypto (Crypto, VRF)
import Cardano.Ledger.Keys (KeyHash, KeyRole (BlockIssuer))
import qualified Cardano.Ledger.Shelley.API as SL
import qualified Cardano.Protocol.TPraos.OCert as OCert
import Cardano.Slotting.Block (BlockNo)
import Cardano.Slotting.Slot (SlotNo)
import Data.Function (on)
import Data.Map.Strict (Map)
import Data.Ord (Down (Down))
import Data.Word (Word64)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)
import Ouroboros.Consensus.Protocol.Abstract
newtype MaxMajorProtVer = MaxMajorProtVer
{ MaxMajorProtVer -> Version
getMaxMajorProtVer :: SL.Version
}
deriving (MaxMajorProtVer -> MaxMajorProtVer -> Bool
(MaxMajorProtVer -> MaxMajorProtVer -> Bool)
-> (MaxMajorProtVer -> MaxMajorProtVer -> Bool)
-> Eq MaxMajorProtVer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MaxMajorProtVer -> MaxMajorProtVer -> Bool
== :: MaxMajorProtVer -> MaxMajorProtVer -> Bool
$c/= :: MaxMajorProtVer -> MaxMajorProtVer -> Bool
/= :: MaxMajorProtVer -> MaxMajorProtVer -> Bool
Eq, Int -> MaxMajorProtVer -> ShowS
[MaxMajorProtVer] -> ShowS
MaxMajorProtVer -> String
(Int -> MaxMajorProtVer -> ShowS)
-> (MaxMajorProtVer -> String)
-> ([MaxMajorProtVer] -> ShowS)
-> Show MaxMajorProtVer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MaxMajorProtVer -> ShowS
showsPrec :: Int -> MaxMajorProtVer -> ShowS
$cshow :: MaxMajorProtVer -> String
show :: MaxMajorProtVer -> String
$cshowList :: [MaxMajorProtVer] -> ShowS
showList :: [MaxMajorProtVer] -> ShowS
Show, (forall x. MaxMajorProtVer -> Rep MaxMajorProtVer x)
-> (forall x. Rep MaxMajorProtVer x -> MaxMajorProtVer)
-> Generic MaxMajorProtVer
forall x. Rep MaxMajorProtVer x -> MaxMajorProtVer
forall x. MaxMajorProtVer -> Rep MaxMajorProtVer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MaxMajorProtVer -> Rep MaxMajorProtVer x
from :: forall x. MaxMajorProtVer -> Rep MaxMajorProtVer x
$cto :: forall x. Rep MaxMajorProtVer x -> MaxMajorProtVer
to :: forall x. Rep MaxMajorProtVer x -> MaxMajorProtVer
Generic)
deriving newtype Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo)
Proxy MaxMajorProtVer -> String
(Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo))
-> (Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo))
-> (Proxy MaxMajorProtVer -> String)
-> NoThunks MaxMajorProtVer
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo)
noThunks :: Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> MaxMajorProtVer -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy MaxMajorProtVer -> String
showTypeOf :: Proxy MaxMajorProtVer -> String
NoThunks
data PraosChainSelectView c = PraosChainSelectView
{ forall c. PraosChainSelectView c -> BlockNo
csvChainLength :: BlockNo,
forall c. PraosChainSelectView c -> SlotNo
csvSlotNo :: SlotNo,
forall c. PraosChainSelectView c -> VKey 'BlockIssuer c
csvIssuer :: SL.VKey 'SL.BlockIssuer c,
forall c. PraosChainSelectView c -> Word64
csvIssueNo :: Word64,
forall c. PraosChainSelectView c -> OutputVRF (VRF c)
csvTieBreakVRF :: VRF.OutputVRF (VRF c)
}
deriving (Int -> PraosChainSelectView c -> ShowS
[PraosChainSelectView c] -> ShowS
PraosChainSelectView c -> String
(Int -> PraosChainSelectView c -> ShowS)
-> (PraosChainSelectView c -> String)
-> ([PraosChainSelectView c] -> ShowS)
-> Show (PraosChainSelectView c)
forall c. Crypto c => Int -> PraosChainSelectView c -> ShowS
forall c. Crypto c => [PraosChainSelectView c] -> ShowS
forall c. Crypto c => PraosChainSelectView c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall c. Crypto c => Int -> PraosChainSelectView c -> ShowS
showsPrec :: Int -> PraosChainSelectView c -> ShowS
$cshow :: forall c. Crypto c => PraosChainSelectView c -> String
show :: PraosChainSelectView c -> String
$cshowList :: forall c. Crypto c => [PraosChainSelectView c] -> ShowS
showList :: [PraosChainSelectView c] -> ShowS
Show, PraosChainSelectView c -> PraosChainSelectView c -> Bool
(PraosChainSelectView c -> PraosChainSelectView c -> Bool)
-> (PraosChainSelectView c -> PraosChainSelectView c -> Bool)
-> Eq (PraosChainSelectView c)
forall c.
Crypto c =>
PraosChainSelectView c -> PraosChainSelectView c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall c.
Crypto c =>
PraosChainSelectView c -> PraosChainSelectView c -> Bool
== :: PraosChainSelectView c -> PraosChainSelectView c -> Bool
$c/= :: forall c.
Crypto c =>
PraosChainSelectView c -> PraosChainSelectView c -> Bool
/= :: PraosChainSelectView c -> PraosChainSelectView c -> Bool
Eq, (forall x.
PraosChainSelectView c -> Rep (PraosChainSelectView c) x)
-> (forall x.
Rep (PraosChainSelectView c) x -> PraosChainSelectView c)
-> Generic (PraosChainSelectView c)
forall x. Rep (PraosChainSelectView c) x -> PraosChainSelectView c
forall x. PraosChainSelectView c -> Rep (PraosChainSelectView c) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x.
Rep (PraosChainSelectView c) x -> PraosChainSelectView c
forall c x.
PraosChainSelectView c -> Rep (PraosChainSelectView c) x
$cfrom :: forall c x.
PraosChainSelectView c -> Rep (PraosChainSelectView c) x
from :: forall x. PraosChainSelectView c -> Rep (PraosChainSelectView c) x
$cto :: forall c x.
Rep (PraosChainSelectView c) x -> PraosChainSelectView c
to :: forall x. Rep (PraosChainSelectView c) x -> PraosChainSelectView c
Generic, Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
Proxy (PraosChainSelectView c) -> String
(Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo))
-> (Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo))
-> (Proxy (PraosChainSelectView c) -> String)
-> NoThunks (PraosChainSelectView c)
forall c.
Crypto c =>
Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
forall c. Crypto c => Proxy (PraosChainSelectView c) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: forall c.
Crypto c =>
Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
noThunks :: Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall c.
Crypto c =>
Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> PraosChainSelectView c -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall c. Crypto c => Proxy (PraosChainSelectView c) -> String
showTypeOf :: Proxy (PraosChainSelectView c) -> String
NoThunks)
data VRFTiebreakerFlavor =
UnrestrictedVRFTiebreaker
|
RestrictedVRFTiebreaker SlotNo
deriving stock (Int -> VRFTiebreakerFlavor -> ShowS
[VRFTiebreakerFlavor] -> ShowS
VRFTiebreakerFlavor -> String
(Int -> VRFTiebreakerFlavor -> ShowS)
-> (VRFTiebreakerFlavor -> String)
-> ([VRFTiebreakerFlavor] -> ShowS)
-> Show VRFTiebreakerFlavor
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VRFTiebreakerFlavor -> ShowS
showsPrec :: Int -> VRFTiebreakerFlavor -> ShowS
$cshow :: VRFTiebreakerFlavor -> String
show :: VRFTiebreakerFlavor -> String
$cshowList :: [VRFTiebreakerFlavor] -> ShowS
showList :: [VRFTiebreakerFlavor] -> ShowS
Show, VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool
(VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool)
-> (VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool)
-> Eq VRFTiebreakerFlavor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool
== :: VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool
$c/= :: VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool
/= :: VRFTiebreakerFlavor -> VRFTiebreakerFlavor -> Bool
Eq, (forall x. VRFTiebreakerFlavor -> Rep VRFTiebreakerFlavor x)
-> (forall x. Rep VRFTiebreakerFlavor x -> VRFTiebreakerFlavor)
-> Generic VRFTiebreakerFlavor
forall x. Rep VRFTiebreakerFlavor x -> VRFTiebreakerFlavor
forall x. VRFTiebreakerFlavor -> Rep VRFTiebreakerFlavor x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. VRFTiebreakerFlavor -> Rep VRFTiebreakerFlavor x
from :: forall x. VRFTiebreakerFlavor -> Rep VRFTiebreakerFlavor x
$cto :: forall x. Rep VRFTiebreakerFlavor x -> VRFTiebreakerFlavor
to :: forall x. Rep VRFTiebreakerFlavor x -> VRFTiebreakerFlavor
Generic)
deriving anyclass (Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo)
Proxy VRFTiebreakerFlavor -> String
(Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo))
-> (Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo))
-> (Proxy VRFTiebreakerFlavor -> String)
-> NoThunks VRFTiebreakerFlavor
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo)
noThunks :: Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> VRFTiebreakerFlavor -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy VRFTiebreakerFlavor -> String
showTypeOf :: Proxy VRFTiebreakerFlavor -> String
NoThunks)
comparePraos ::
Crypto c
=> VRFTiebreakerFlavor
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
comparePraos :: forall c.
Crypto c =>
VRFTiebreakerFlavor
-> PraosChainSelectView c -> PraosChainSelectView c -> Ordering
comparePraos VRFTiebreakerFlavor
tiebreakerFlavor =
(BlockNo -> BlockNo -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BlockNo -> BlockNo -> Ordering)
-> (PraosChainSelectView c -> BlockNo)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PraosChainSelectView c -> BlockNo
forall c. PraosChainSelectView c -> BlockNo
csvChainLength)
(PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> (PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall a. Semigroup a => a -> a -> a
<> (PraosChainSelectView c -> PraosChainSelectView c -> Bool)
-> (PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall a.
(a -> a -> Bool) -> (a -> a -> Ordering) -> a -> a -> Ordering
when' PraosChainSelectView c -> PraosChainSelectView c -> Bool
forall c.
Crypto c =>
PraosChainSelectView c -> PraosChainSelectView c -> Bool
issueNoArmed (Word64 -> Word64 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Word64 -> Word64 -> Ordering)
-> (PraosChainSelectView c -> Word64)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PraosChainSelectView c -> Word64
forall c. PraosChainSelectView c -> Word64
csvIssueNo)
(PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> (PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall a. Semigroup a => a -> a -> a
<> (PraosChainSelectView c -> PraosChainSelectView c -> Bool)
-> (PraosChainSelectView c -> PraosChainSelectView c -> Ordering)
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall a.
(a -> a -> Bool) -> (a -> a -> Ordering) -> a -> a -> Ordering
when' PraosChainSelectView c -> PraosChainSelectView c -> Bool
vrfArmed (Down (OutputVRF (VRF c)) -> Down (OutputVRF (VRF c)) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Down (OutputVRF (VRF c)) -> Down (OutputVRF (VRF c)) -> Ordering)
-> (PraosChainSelectView c -> Down (OutputVRF (VRF c)))
-> PraosChainSelectView c
-> PraosChainSelectView c
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` OutputVRF (VRF c) -> Down (OutputVRF (VRF c))
forall a. a -> Down a
Down (OutputVRF (VRF c) -> Down (OutputVRF (VRF c)))
-> (PraosChainSelectView c -> OutputVRF (VRF c))
-> PraosChainSelectView c
-> Down (OutputVRF (VRF c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PraosChainSelectView c -> OutputVRF (VRF c)
forall c. PraosChainSelectView c -> OutputVRF (VRF c)
csvTieBreakVRF)
where
when' ::
(a -> a -> Bool)
-> (a -> a -> Ordering)
-> (a -> a -> Ordering)
when' :: forall a.
(a -> a -> Bool) -> (a -> a -> Ordering) -> a -> a -> Ordering
when' a -> a -> Bool
p a -> a -> Ordering
comp a
a1 a
a2 =
if a -> a -> Bool
p a
a1 a
a2 then a -> a -> Ordering
comp a
a1 a
a2 else Ordering
EQ
issueNoArmed :: PraosChainSelectView c -> PraosChainSelectView c -> Bool
issueNoArmed PraosChainSelectView c
v1 PraosChainSelectView c
v2 =
PraosChainSelectView c -> SlotNo
forall c. PraosChainSelectView c -> SlotNo
csvSlotNo PraosChainSelectView c
v1 SlotNo -> SlotNo -> Bool
forall a. Eq a => a -> a -> Bool
== PraosChainSelectView c -> SlotNo
forall c. PraosChainSelectView c -> SlotNo
csvSlotNo PraosChainSelectView c
v2
Bool -> Bool -> Bool
&& PraosChainSelectView c -> VKey 'BlockIssuer c
forall c. PraosChainSelectView c -> VKey 'BlockIssuer c
csvIssuer PraosChainSelectView c
v1 VKey 'BlockIssuer c -> VKey 'BlockIssuer c -> Bool
forall a. Eq a => a -> a -> Bool
== PraosChainSelectView c -> VKey 'BlockIssuer c
forall c. PraosChainSelectView c -> VKey 'BlockIssuer c
csvIssuer PraosChainSelectView c
v2
vrfArmed :: PraosChainSelectView c -> PraosChainSelectView c -> Bool
vrfArmed PraosChainSelectView c
v1 PraosChainSelectView c
v2 = case VRFTiebreakerFlavor
tiebreakerFlavor of
VRFTiebreakerFlavor
UnrestrictedVRFTiebreaker -> Bool
True
RestrictedVRFTiebreaker SlotNo
maxDist ->
SlotNo -> SlotNo -> SlotNo
slotDist (PraosChainSelectView c -> SlotNo
forall c. PraosChainSelectView c -> SlotNo
csvSlotNo PraosChainSelectView c
v1) (PraosChainSelectView c -> SlotNo
forall c. PraosChainSelectView c -> SlotNo
csvSlotNo PraosChainSelectView c
v2) SlotNo -> SlotNo -> Bool
forall a. Ord a => a -> a -> Bool
<= SlotNo
maxDist
slotDist :: SlotNo -> SlotNo -> SlotNo
slotDist :: SlotNo -> SlotNo -> SlotNo
slotDist SlotNo
s SlotNo
t
| SlotNo
s SlotNo -> SlotNo -> Bool
forall a. Ord a => a -> a -> Bool
>= SlotNo
t = SlotNo
s SlotNo -> SlotNo -> SlotNo
forall a. Num a => a -> a -> a
- SlotNo
t
| Bool
otherwise = SlotNo
t SlotNo -> SlotNo -> SlotNo
forall a. Num a => a -> a -> a
- SlotNo
s
instance Crypto c => Ord (PraosChainSelectView c) where
compare :: PraosChainSelectView c -> PraosChainSelectView c -> Ordering
compare = VRFTiebreakerFlavor
-> PraosChainSelectView c -> PraosChainSelectView c -> Ordering
forall c.
Crypto c =>
VRFTiebreakerFlavor
-> PraosChainSelectView c -> PraosChainSelectView c -> Ordering
comparePraos VRFTiebreakerFlavor
UnrestrictedVRFTiebreaker
instance Crypto c => ChainOrder (PraosChainSelectView c) where
type ChainOrderConfig (PraosChainSelectView c) = VRFTiebreakerFlavor
preferCandidate :: ChainOrderConfig (PraosChainSelectView c)
-> PraosChainSelectView c -> PraosChainSelectView c -> Bool
preferCandidate ChainOrderConfig (PraosChainSelectView c)
cfg PraosChainSelectView c
ours PraosChainSelectView c
cand = VRFTiebreakerFlavor
-> PraosChainSelectView c -> PraosChainSelectView c -> Ordering
forall c.
Crypto c =>
VRFTiebreakerFlavor
-> PraosChainSelectView c -> PraosChainSelectView c -> Ordering
comparePraos ChainOrderConfig (PraosChainSelectView c)
VRFTiebreakerFlavor
cfg PraosChainSelectView c
ours PraosChainSelectView c
cand Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT
data PraosCanBeLeader c = PraosCanBeLeader
{
forall c. PraosCanBeLeader c -> OCert c
praosCanBeLeaderOpCert :: !(OCert.OCert c),
forall c. PraosCanBeLeader c -> VKey 'BlockIssuer c
praosCanBeLeaderColdVerKey :: !(SL.VKey 'SL.BlockIssuer c),
forall c. PraosCanBeLeader c -> SignKeyVRF c
praosCanBeLeaderSignKeyVRF :: !(SL.SignKeyVRF c)
}
deriving ((forall x. PraosCanBeLeader c -> Rep (PraosCanBeLeader c) x)
-> (forall x. Rep (PraosCanBeLeader c) x -> PraosCanBeLeader c)
-> Generic (PraosCanBeLeader c)
forall x. Rep (PraosCanBeLeader c) x -> PraosCanBeLeader c
forall x. PraosCanBeLeader c -> Rep (PraosCanBeLeader c) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (PraosCanBeLeader c) x -> PraosCanBeLeader c
forall c x. PraosCanBeLeader c -> Rep (PraosCanBeLeader c) x
$cfrom :: forall c x. PraosCanBeLeader c -> Rep (PraosCanBeLeader c) x
from :: forall x. PraosCanBeLeader c -> Rep (PraosCanBeLeader c) x
$cto :: forall c x. Rep (PraosCanBeLeader c) x -> PraosCanBeLeader c
to :: forall x. Rep (PraosCanBeLeader c) x -> PraosCanBeLeader c
Generic)
instance Crypto c => NoThunks (PraosCanBeLeader c)
data PraosNonces = PraosNonces {
PraosNonces -> Nonce
candidateNonce :: !Nonce
, PraosNonces -> Nonce
epochNonce :: !Nonce
, PraosNonces -> Nonce
evolvingNonce :: !Nonce
, PraosNonces -> Nonce
labNonce :: !Nonce
, PraosNonces -> Nonce
previousLabNonce :: !Nonce
}
class ConsensusProtocol p => PraosProtocolSupportsNode p where
type PraosProtocolSupportsNodeCrypto p
getPraosNonces :: proxy p -> ChainDepState p -> PraosNonces
getOpCertCounters :: proxy p -> ChainDepState p -> Map (KeyHash 'BlockIssuer (PraosProtocolSupportsNodeCrypto p)) Word64