{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
module Ouroboros.Consensus.Peras.Vote.Aggregation
( PerasRoundVoteState
, getPerasRoundVoteStateRound
, getPerasRoundVoteStateCertMaybe
, getPerasRoundVoteStateMaxTargetedSlot
, pattern VoteGeneratedNewCert
, pattern VoteDidntGenerateNewCert
, updatePerasRoundVoteStates
, UpdateRoundVoteStateError (..)
, PerasTargetVoteState
, getPerasTargetVoteStateTotalWeight
, getPerasTargetVoteStateBlock
) where
import Control.Exception (assert)
import Data.Functor.Compose (Compose (..))
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Word (Word64)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..))
import Ouroboros.Consensus.Block
import Ouroboros.Consensus.BlockchainTime (WithArrivalTime)
data PerasRoundVoteState blk = PerasRoundVoteState
{ forall blk. PerasRoundVoteState blk -> PerasRoundNo
prvsRoundNo :: !PerasRoundNo
, forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState :: !(Either (NoQuorum blk) (Quorum blk))
}
deriving instance
( StandardHash blk
, Show (PerasVote blk)
, Show (PerasCert blk)
, Show (PerasVotingCommittee blk)
) =>
Show (PerasRoundVoteState blk)
deriving instance
( StandardHash blk
, Eq (PerasVote blk)
, Eq (PerasCert blk)
, Eq (PerasVotingCommittee blk)
) =>
Eq (PerasRoundVoteState blk)
deriving instance
( StandardHash blk
, NoThunks (PerasVote blk)
, NoThunks (PerasCert blk)
, NoThunks (PerasVotingCommittee blk)
) =>
NoThunks (PerasRoundVoteState blk)
deriving instance
Generic (PerasRoundVoteState blk)
data NoQuorum blk = NoQuorum
{ forall blk.
NoQuorum blk
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates :: !(Map (Point blk) (PerasTargetVoteState blk 'Candidate))
}
deriving instance
( StandardHash blk
, Show (PerasVote blk)
, Show (PerasCert blk)
) =>
Show (NoQuorum blk)
deriving instance
( StandardHash blk
, Eq (PerasVote blk)
, Eq (PerasCert blk)
) =>
Eq (NoQuorum blk)
deriving instance
( StandardHash blk
, NoThunks (PerasVote blk)
, NoThunks (PerasCert blk)
) =>
NoThunks (NoQuorum blk)
deriving instance
Generic (NoQuorum blk)
data Quorum blk = Quorum
{ forall blk. Quorum blk -> Word64
excessVotes :: !Word64
, forall blk.
Quorum blk -> Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates :: !(Map (Point blk) (PerasTargetVoteState blk 'Loser))
, forall blk. Quorum blk -> PerasTargetVoteState blk 'Winner
winnerState :: !(PerasTargetVoteState blk 'Winner)
}
deriving instance
( StandardHash blk
, Show (PerasVote blk)
, Show (PerasCert blk)
) =>
Show (Quorum blk)
deriving instance
( StandardHash blk
, Eq (PerasVote blk)
, Eq (PerasCert blk)
) =>
Eq (Quorum blk)
deriving instance
( StandardHash blk
, NoThunks (PerasVote blk)
, NoThunks (PerasCert blk)
) =>
NoThunks (Quorum blk)
deriving instance
Generic (Quorum blk)
getPerasRoundVoteStateRound :: PerasRoundVoteState blk -> PerasRoundNo
getPerasRoundVoteStateRound :: forall blk. PerasRoundVoteState blk -> PerasRoundNo
getPerasRoundVoteStateRound = PerasRoundVoteState blk -> PerasRoundNo
forall blk. PerasRoundVoteState blk -> PerasRoundNo
prvsRoundNo
getPerasRoundVoteStateCertMaybe ::
PerasRoundVoteState blk ->
Maybe (ValidatedPerasCert blk)
getPerasRoundVoteStateCertMaybe :: forall blk.
PerasRoundVoteState blk -> Maybe (ValidatedPerasCert blk)
getPerasRoundVoteStateCertMaybe = \case
PerasRoundVoteState
{ prvsState :: forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState =
Right
Quorum
{ winnerState :: forall blk. Quorum blk -> PerasTargetVoteState blk 'Winner
winnerState =
PerasTargetVoteWinner PerasVoteCollection blk
_ ValidatedPerasCert blk
cert
}
} ->
ValidatedPerasCert blk -> Maybe (ValidatedPerasCert blk)
forall a. a -> Maybe a
Just ValidatedPerasCert blk
cert
PerasRoundVoteState blk
_ ->
Maybe (ValidatedPerasCert blk)
forall a. Maybe a
Nothing
getPerasRoundVoteStateMaxTargetedSlot ::
PerasRoundVoteState blk ->
WithOrigin SlotNo
getPerasRoundVoteStateMaxTargetedSlot :: forall blk. PerasRoundVoteState blk -> WithOrigin SlotNo
getPerasRoundVoteStateMaxTargetedSlot PerasRoundVoteState{Either (NoQuorum blk) (Quorum blk)
prvsState :: forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState :: Either (NoQuorum blk) (Quorum blk)
prvsState} =
case Either (NoQuorum blk) (Quorum blk)
prvsState of
Left NoQuorum{Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates :: forall blk.
NoQuorum blk
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates :: Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates} ->
[WithOrigin SlotNo] -> WithOrigin SlotNo
forall {t}. Ord t => [WithOrigin t] -> WithOrigin t
maximumOrOrigin ([WithOrigin SlotNo] -> WithOrigin SlotNo)
-> [WithOrigin SlotNo] -> WithOrigin SlotNo
forall a b. (a -> b) -> a -> b
$ (Point blk -> WithOrigin SlotNo)
-> [Point blk] -> [WithOrigin SlotNo]
forall a b. (a -> b) -> [a] -> [b]
map Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot ([Point blk] -> [WithOrigin SlotNo])
-> [Point blk] -> [WithOrigin SlotNo]
forall a b. (a -> b) -> a -> b
$ Map (Point blk) (PerasTargetVoteState blk 'Candidate)
-> [Point blk]
forall k a. Map k a -> [k]
Map.keys Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates
Right Quorum{PerasTargetVoteState blk 'Winner
winnerState :: forall blk. Quorum blk -> PerasTargetVoteState blk 'Winner
winnerState :: PerasTargetVoteState blk 'Winner
winnerState, Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates :: forall blk.
Quorum blk -> Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates :: Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates} ->
[WithOrigin SlotNo] -> WithOrigin SlotNo
forall {t}. Ord t => [WithOrigin t] -> WithOrigin t
maximumOrOrigin ([WithOrigin SlotNo] -> WithOrigin SlotNo)
-> [WithOrigin SlotNo] -> WithOrigin SlotNo
forall a b. (a -> b) -> a -> b
$
Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot (PerasTargetVoteState blk 'Winner -> Point blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> Point blk
getPerasTargetVoteStateBlock PerasTargetVoteState blk 'Winner
winnerState)
WithOrigin SlotNo -> [WithOrigin SlotNo] -> [WithOrigin SlotNo]
forall a. a -> [a] -> [a]
: (Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot (Point blk -> WithOrigin SlotNo)
-> [Point blk] -> [WithOrigin SlotNo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map (Point blk) (PerasTargetVoteState blk 'Loser) -> [Point blk]
forall k a. Map k a -> [k]
Map.keys Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates)
where
maximumOrOrigin :: [WithOrigin t] -> WithOrigin t
maximumOrOrigin [] = WithOrigin t
forall t. WithOrigin t
Origin
maximumOrOrigin [WithOrigin t]
xs = [WithOrigin t] -> WithOrigin t
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [WithOrigin t]
xs
freshRoundVoteState ::
PerasRoundNo ->
PerasRoundVoteState blk
freshRoundVoteState :: forall blk. PerasRoundNo -> PerasRoundVoteState blk
freshRoundVoteState PerasRoundNo
roundNo =
PerasRoundVoteState
{ prvsRoundNo :: PerasRoundNo
prvsRoundNo = PerasRoundNo
roundNo
, prvsState :: Either (NoQuorum blk) (Quorum blk)
prvsState =
NoQuorum blk -> Either (NoQuorum blk) (Quorum blk)
forall a b. a -> Either a b
Left
NoQuorum
{ candidateStates :: Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates =
Map (Point blk) (PerasTargetVoteState blk 'Candidate)
forall k a. Map k a
Map.empty
}
}
data UpdateRoundVoteStateError blk
= RoundVoteStateLoserAboveQuorum
(PerasTargetVoteState blk 'Winner)
(PerasTargetVoteState blk 'Loser)
| RoundVoteStateForgingCertError
(PerasError blk)
updatePerasRoundVoteState ::
forall blk.
StandardHash blk =>
WithArrivalTime (ValidatedPerasVote blk) ->
PerasParams blk ->
PerasRoundVoteState blk ->
Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
updatePerasRoundVoteState :: forall blk.
StandardHash blk =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasParams blk
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
updatePerasRoundVoteState WithArrivalTime (ValidatedPerasVote blk)
vote PerasParams blk
params PerasRoundVoteState blk
roundState =
Bool
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (WithArrivalTime (ValidatedPerasVote blk) -> PerasRoundNo
forall vote blk. IsPerasVote vote blk => vote -> PerasRoundNo
getPerasVoteRound WithArrivalTime (ValidatedPerasVote blk)
vote PerasRoundNo -> PerasRoundNo -> Bool
forall a. Eq a => a -> a -> Bool
== PerasRoundVoteState blk -> PerasRoundNo
forall blk. PerasRoundVoteState blk -> PerasRoundNo
prvsRoundNo PerasRoundVoteState blk
roundState) (Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk) (PerasRoundVoteState blk))
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a b. (a -> b) -> a -> b
$ do
case PerasRoundVoteState blk
roundState of
state :: PerasRoundVoteState blk
state@PerasRoundVoteState
{ prvsState :: forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState =
Left
NoQuorum
{ Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates :: forall blk.
NoQuorum blk
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates :: Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates
}
} -> do
let updateMaybeCandidateState :: Maybe (PerasTargetVoteState blk 'Candidate)
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
updateMaybeCandidateState = \case
Maybe (PerasTargetVoteState blk 'Candidate)
Nothing ->
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall blk.
BlockSupportsPeras blk =>
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
candidateOrWinnerVoteStateSingleton PerasParams blk
params WithArrivalTime (ValidatedPerasVote blk)
vote
Just PerasTargetVoteState blk 'Candidate
oldCandidateState ->
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Candidate
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall blk.
StandardHash blk =>
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Candidate
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
updateCandidateVoteState PerasParams blk
params WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Candidate
oldCandidateState
candidateOrWinnerState <-
Maybe (PerasTargetVoteState blk 'Candidate)
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
updateMaybeCandidateState (Point blk
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
-> Maybe (PerasTargetVoteState blk 'Candidate)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (WithArrivalTime (ValidatedPerasVote blk) -> Point blk
forall vote blk. IsPerasVote vote blk => vote -> Point blk
getPerasVotePoint WithArrivalTime (ValidatedPerasVote blk)
vote) Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates)
case candidateOrWinnerState of
RemainedCandidate PerasTargetVoteState blk 'Candidate
newCandidateState -> do
let prvsCandidateStates' :: Map (Point blk) (PerasTargetVoteState blk 'Candidate)
prvsCandidateStates' =
Point blk
-> PerasTargetVoteState blk 'Candidate
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert
(WithArrivalTime (ValidatedPerasVote blk) -> Point blk
forall vote blk. IsPerasVote vote blk => vote -> Point blk
getPerasVotePoint WithArrivalTime (ValidatedPerasVote blk)
vote)
PerasTargetVoteState blk 'Candidate
newCandidateState
Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates
PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a. a -> Either (UpdateRoundVoteStateError blk) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PerasRoundVoteState blk
-> Either
(UpdateRoundVoteStateError blk) (PerasRoundVoteState blk))
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a b. (a -> b) -> a -> b
$
PerasRoundVoteState blk
state
{ prvsState =
Left
NoQuorum
{ candidateStates = prvsCandidateStates'
}
}
BecameWinner PerasTargetVoteState blk 'Winner
winnerState -> do
let winnerPoint :: Point blk
winnerPoint =
PerasVoteTarget blk -> Point blk
forall blk. PerasVoteTarget blk -> Point blk
pvtBlock (PerasVoteCollection blk -> PerasVoteTarget blk
forall blk. PerasVoteCollection blk -> PerasVoteTarget blk
pvcTarget (PerasTargetVoteState blk 'Winner -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Winner
winnerState))
loserStates :: Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates =
PerasTargetVoteState blk 'Candidate
-> PerasTargetVoteState blk 'Loser
forall blk.
PerasTargetVoteState blk 'Candidate
-> PerasTargetVoteState blk 'Loser
candidateToLoser (PerasTargetVoteState blk 'Candidate
-> PerasTargetVoteState blk 'Loser)
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
-> Map (Point blk) (PerasTargetVoteState blk 'Loser)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Point blk
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
-> Map (Point blk) (PerasTargetVoteState blk 'Candidate)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete Point blk
winnerPoint Map (Point blk) (PerasTargetVoteState blk 'Candidate)
candidateStates
PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a. a -> Either (UpdateRoundVoteStateError blk) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PerasRoundVoteState blk
-> Either
(UpdateRoundVoteStateError blk) (PerasRoundVoteState blk))
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a b. (a -> b) -> a -> b
$
PerasRoundVoteState
{ prvsRoundNo :: PerasRoundNo
prvsRoundNo =
PerasRoundVoteState blk -> PerasRoundNo
forall blk. PerasRoundVoteState blk -> PerasRoundNo
prvsRoundNo PerasRoundVoteState blk
roundState
, prvsState :: Either (NoQuorum blk) (Quorum blk)
prvsState =
Quorum blk -> Either (NoQuorum blk) (Quorum blk)
forall a b. b -> Either a b
Right
Quorum
{ excessVotes :: Word64
excessVotes = Word64
0
, loserStates :: Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates = Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates
, winnerState :: PerasTargetVoteState blk 'Winner
winnerState = PerasTargetVoteState blk 'Winner
winnerState
}
}
state :: PerasRoundVoteState blk
state@PerasRoundVoteState
{ prvsState :: forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState =
Right
Quorum
{ Word64
excessVotes :: forall blk. Quorum blk -> Word64
excessVotes :: Word64
excessVotes
, PerasTargetVoteState blk 'Winner
winnerState :: forall blk. Quorum blk -> PerasTargetVoteState blk 'Winner
winnerState :: PerasTargetVoteState blk 'Winner
winnerState
, Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates :: forall blk.
Quorum blk -> Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates :: Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates
}
} -> do
let votePoint :: Point blk
votePoint =
WithArrivalTime (ValidatedPerasVote blk) -> Point blk
forall vote blk. IsPerasVote vote blk => vote -> Point blk
getPerasVotePoint WithArrivalTime (ValidatedPerasVote blk)
vote
winnerPoint :: Point blk
winnerPoint =
PerasVoteTarget blk -> Point blk
forall blk. PerasVoteTarget blk -> Point blk
pvtBlock (PerasVoteCollection blk -> PerasVoteTarget blk
forall blk. PerasVoteCollection blk -> PerasVoteTarget blk
pvcTarget (PerasTargetVoteState blk 'Winner -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Winner
winnerState))
if Point blk
votePoint Point blk -> Point blk -> Bool
forall a. Eq a => a -> a -> Bool
== Point blk
winnerPoint
then do
let winnerState' :: PerasTargetVoteState blk 'Winner
winnerState' =
WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner
forall blk.
(StandardHash blk, IsPerasVote (PerasVote blk) blk) =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner
updateWinnerVoteState WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Winner
winnerState
PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a. a -> Either (UpdateRoundVoteStateError blk) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PerasRoundVoteState blk
-> Either
(UpdateRoundVoteStateError blk) (PerasRoundVoteState blk))
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall a b. (a -> b) -> a -> b
$
PerasRoundVoteState blk
state
{ prvsState =
Right
Quorum
{ excessVotes = excessVotes + 1
, winnerState = winnerState'
, loserStates = loserStates
}
}
else do
let updateMaybeLoserVoteState :: Maybe (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
updateMaybeLoserVoteState = \case
Maybe (PerasTargetVoteState blk 'Loser)
Nothing ->
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall blk.
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
loserVoteStateSingleton PerasParams blk
params PerasTargetVoteState blk 'Winner
winnerState WithArrivalTime (ValidatedPerasVote blk)
vote
Just PerasTargetVoteState blk 'Loser
oldLoserState ->
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall blk.
StandardHash blk =>
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
updateLoserVoteState PerasParams blk
params PerasTargetVoteState blk 'Winner
winnerState WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Loser
oldLoserState
loserStates' <-
(Maybe (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk)
(Maybe (PerasTargetVoteState blk 'Loser)))
-> Point blk
-> Map (Point blk) (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk)
(Map (Point blk) (PerasTargetVoteState blk 'Loser))
forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Map.alterF (\Maybe (PerasTargetVoteState blk 'Loser)
mState -> PerasTargetVoteState blk 'Loser
-> Maybe (PerasTargetVoteState blk 'Loser)
forall a. a -> Maybe a
Just (PerasTargetVoteState blk 'Loser
-> Maybe (PerasTargetVoteState blk 'Loser))
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk)
(Maybe (PerasTargetVoteState blk 'Loser))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
updateMaybeLoserVoteState Maybe (PerasTargetVoteState blk 'Loser)
mState) Point blk
votePoint Map (Point blk) (PerasTargetVoteState blk 'Loser)
loserStates
pure $
state
{ prvsState =
Right
Quorum
{ excessVotes = excessVotes + 1
, winnerState = winnerState
, loserStates = loserStates'
}
}
updatePerasRoundVoteStates ::
forall blk.
StandardHash blk =>
WithArrivalTime (ValidatedPerasVote blk) ->
PerasParams blk ->
Map PerasRoundNo (PerasRoundVoteState blk) ->
Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk, Map PerasRoundNo (PerasRoundVoteState blk))
updatePerasRoundVoteStates :: forall blk.
StandardHash blk =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasParams blk
-> Map PerasRoundNo (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk,
Map PerasRoundNo (PerasRoundVoteState blk))
updatePerasRoundVoteStates WithArrivalTime (ValidatedPerasVote blk)
vote PerasParams blk
params =
(Maybe (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk, PerasRoundVoteState blk))
-> PerasRoundNo
-> Map PerasRoundNo (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk,
Map PerasRoundNo (PerasRoundVoteState blk))
forall k a e.
Ord k =>
(Maybe a -> Either e (a, a))
-> k -> Map k a -> Either e (a, Map k a)
alterMapAndReturnUpdatedValue
Maybe (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk, PerasRoundVoteState blk)
updateMaybePerasRoundVoteState
(WithArrivalTime (ValidatedPerasVote blk) -> PerasRoundNo
forall vote blk. IsPerasVote vote blk => vote -> PerasRoundNo
getPerasVoteRound WithArrivalTime (ValidatedPerasVote blk)
vote)
where
alterMapAndReturnUpdatedValue ::
Ord k =>
(Maybe a -> Either e (a, a)) ->
k ->
Map k a ->
Either e (a, Map k a)
alterMapAndReturnUpdatedValue :: forall k a e.
Ord k =>
(Maybe a -> Either e (a, a))
-> k -> Map k a -> Either e (a, Map k a)
alterMapAndReturnUpdatedValue Maybe a -> Either e (a, a)
f k
k =
Compose (Either e) ((,) a) (Map k a) -> Either e (a, Map k a)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose (Either e) ((,) a) (Map k a) -> Either e (a, Map k a))
-> (Map k a -> Compose (Either e) ((,) a) (Map k a))
-> Map k a
-> Either e (a, Map k a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe a -> Compose (Either e) ((,) a) (Maybe a))
-> k -> Map k a -> Compose (Either e) ((,) a) (Map k a)
forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Map.alterF ((a -> Maybe a)
-> Compose (Either e) ((,) a) a
-> Compose (Either e) ((,) a) (Maybe a)
forall a b.
(a -> b)
-> Compose (Either e) ((,) a) a -> Compose (Either e) ((,) a) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Maybe a
forall a. a -> Maybe a
Just (Compose (Either e) ((,) a) a
-> Compose (Either e) ((,) a) (Maybe a))
-> (Maybe a -> Compose (Either e) ((,) a) a)
-> Maybe a
-> Compose (Either e) ((,) a) (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either e (a, a) -> Compose (Either e) ((,) a) a
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Either e (a, a) -> Compose (Either e) ((,) a) a)
-> (Maybe a -> Either e (a, a))
-> Maybe a
-> Compose (Either e) ((,) a) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> Either e (a, a)
f)) k
k
existingOrFreshRoundVoteState ::
Maybe (PerasRoundVoteState blk) ->
PerasRoundVoteState blk
existingOrFreshRoundVoteState :: Maybe (PerasRoundVoteState blk) -> PerasRoundVoteState blk
existingOrFreshRoundVoteState =
PerasRoundVoteState blk
-> Maybe (PerasRoundVoteState blk) -> PerasRoundVoteState blk
forall a. a -> Maybe a -> a
fromMaybe (PerasRoundNo -> PerasRoundVoteState blk
forall blk. PerasRoundNo -> PerasRoundVoteState blk
freshRoundVoteState (WithArrivalTime (ValidatedPerasVote blk) -> PerasRoundNo
forall vote blk. IsPerasVote vote blk => vote -> PerasRoundNo
getPerasVoteRound WithArrivalTime (ValidatedPerasVote blk)
vote))
updateMaybePerasRoundVoteState ::
Maybe (PerasRoundVoteState blk) ->
Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk, PerasRoundVoteState blk)
updateMaybePerasRoundVoteState :: Maybe (PerasRoundVoteState blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasRoundVoteState blk, PerasRoundVoteState blk)
updateMaybePerasRoundVoteState Maybe (PerasRoundVoteState blk)
mRoundState = do
let roundState :: PerasRoundVoteState blk
roundState = Maybe (PerasRoundVoteState blk) -> PerasRoundVoteState blk
existingOrFreshRoundVoteState Maybe (PerasRoundVoteState blk)
mRoundState
newRoundState <- WithArrivalTime (ValidatedPerasVote blk)
-> PerasParams blk
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
forall blk.
StandardHash blk =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasParams blk
-> PerasRoundVoteState blk
-> Either (UpdateRoundVoteStateError blk) (PerasRoundVoteState blk)
updatePerasRoundVoteState WithArrivalTime (ValidatedPerasVote blk)
vote PerasParams blk
params PerasRoundVoteState blk
roundState
pure (newRoundState, newRoundState)
pattern VoteGeneratedNewCert ::
ValidatedPerasCert blk ->
PerasRoundVoteState blk
pattern $mVoteGeneratedNewCert :: forall {r} {blk}.
PerasRoundVoteState blk
-> (ValidatedPerasCert blk -> r) -> ((# #) -> r) -> r
VoteGeneratedNewCert cert <-
(voteGeneratedCert -> Just cert)
pattern VoteDidntGenerateNewCert ::
PerasRoundVoteState blk
pattern $mVoteDidntGenerateNewCert :: forall {r} {blk}.
PerasRoundVoteState blk -> ((# #) -> r) -> ((# #) -> r) -> r
VoteDidntGenerateNewCert <-
(voteGeneratedCert -> Nothing)
{-# COMPLETE VoteGeneratedNewCert, VoteDidntGenerateNewCert #-}
voteGeneratedCert :: PerasRoundVoteState blk -> Maybe (ValidatedPerasCert blk)
voteGeneratedCert :: forall blk.
PerasRoundVoteState blk -> Maybe (ValidatedPerasCert blk)
voteGeneratedCert = \case
PerasRoundVoteState
{ prvsState :: forall blk.
PerasRoundVoteState blk -> Either (NoQuorum blk) (Quorum blk)
prvsState =
Right
Quorum
{ excessVotes :: forall blk. Quorum blk -> Word64
excessVotes = Word64
0
, winnerState :: forall blk. Quorum blk -> PerasTargetVoteState blk 'Winner
winnerState = PerasTargetVoteWinner PerasVoteCollection blk
_ ValidatedPerasCert blk
cert
}
} ->
ValidatedPerasCert blk -> Maybe (ValidatedPerasCert blk)
forall a. a -> Maybe a
Just ValidatedPerasCert blk
cert
PerasRoundVoteState blk
_ ->
Maybe (ValidatedPerasCert blk)
forall a. Maybe a
Nothing
data PerasTargetVoteStatus
= Candidate
| Winner
| Loser
deriving stock (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
(PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> Eq PerasTargetVoteStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
== :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
$c/= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
/= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
Eq, Eq PerasTargetVoteStatus
Eq PerasTargetVoteStatus =>
(PerasTargetVoteStatus -> PerasTargetVoteStatus -> Ordering)
-> (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> (PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool)
-> (PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus)
-> (PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus)
-> Ord PerasTargetVoteStatus
PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
PerasTargetVoteStatus -> PerasTargetVoteStatus -> Ordering
PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus
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 :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Ordering
compare :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Ordering
$c< :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
< :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
$c<= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
<= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
$c> :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
> :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
$c>= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
>= :: PerasTargetVoteStatus -> PerasTargetVoteStatus -> Bool
$cmax :: PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus
max :: PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus
$cmin :: PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus
min :: PerasTargetVoteStatus
-> PerasTargetVoteStatus -> PerasTargetVoteStatus
Ord, Int -> PerasTargetVoteStatus -> ShowS
[PerasTargetVoteStatus] -> ShowS
PerasTargetVoteStatus -> String
(Int -> PerasTargetVoteStatus -> ShowS)
-> (PerasTargetVoteStatus -> String)
-> ([PerasTargetVoteStatus] -> ShowS)
-> Show PerasTargetVoteStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PerasTargetVoteStatus -> ShowS
showsPrec :: Int -> PerasTargetVoteStatus -> ShowS
$cshow :: PerasTargetVoteStatus -> String
show :: PerasTargetVoteStatus -> String
$cshowList :: [PerasTargetVoteStatus] -> ShowS
showList :: [PerasTargetVoteStatus] -> ShowS
Show, (forall x. PerasTargetVoteStatus -> Rep PerasTargetVoteStatus x)
-> (forall x. Rep PerasTargetVoteStatus x -> PerasTargetVoteStatus)
-> Generic PerasTargetVoteStatus
forall x. Rep PerasTargetVoteStatus x -> PerasTargetVoteStatus
forall x. PerasTargetVoteStatus -> Rep PerasTargetVoteStatus x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PerasTargetVoteStatus -> Rep PerasTargetVoteStatus x
from :: forall x. PerasTargetVoteStatus -> Rep PerasTargetVoteStatus x
$cto :: forall x. Rep PerasTargetVoteStatus x -> PerasTargetVoteStatus
to :: forall x. Rep PerasTargetVoteStatus x -> PerasTargetVoteStatus
Generic)
deriving anyclass Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo)
Proxy PerasTargetVoteStatus -> String
(Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo))
-> (Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo))
-> (Proxy PerasTargetVoteStatus -> String)
-> NoThunks PerasTargetVoteStatus
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo)
noThunks :: Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> PerasTargetVoteStatus -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy PerasTargetVoteStatus -> String
showTypeOf :: Proxy PerasTargetVoteStatus -> String
NoThunks
data PerasTargetVoteState blk (status :: PerasTargetVoteStatus) where
PerasTargetVoteCandidate ::
!(PerasVoteCollection blk) ->
PerasTargetVoteState blk 'Candidate
PerasTargetVoteLoser ::
!(PerasVoteCollection blk) ->
PerasTargetVoteState blk 'Loser
PerasTargetVoteWinner ::
!(PerasVoteCollection blk) ->
!(ValidatedPerasCert blk) ->
PerasTargetVoteState blk 'Winner
deriving stock instance
( Eq (PerasVoteCollection blk)
, Eq (ValidatedPerasCert blk)
) =>
Eq (PerasTargetVoteState blk status)
deriving stock instance
( Ord (PerasVoteCollection blk)
, Ord (ValidatedPerasCert blk)
) =>
Ord (PerasTargetVoteState blk status)
deriving stock instance
( Show (PerasVoteCollection blk)
, Show (ValidatedPerasCert blk)
) =>
Show (PerasTargetVoteState blk status)
instance
( NoThunks (PerasVoteCollection blk)
, NoThunks (ValidatedPerasCert blk)
) =>
NoThunks (PerasTargetVoteState blk status)
where
showTypeOf :: Proxy (PerasTargetVoteState blk status) -> String
showTypeOf Proxy (PerasTargetVoteState blk status)
_ = String
"PerasTargetVoteState"
wNoThunks :: Context -> PerasTargetVoteState blk status -> IO (Maybe ThunkInfo)
wNoThunks = Context -> PerasTargetVoteState blk status -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks
noThunks :: Context -> PerasTargetVoteState blk status -> IO (Maybe ThunkInfo)
noThunks Context
ctx (PerasTargetVoteCandidate PerasVoteCollection blk
voteCollection) =
Context -> PerasVoteCollection blk -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx PerasVoteCollection blk
voteCollection
noThunks Context
ctx (PerasTargetVoteLoser PerasVoteCollection blk
voteCollection) =
Context -> PerasVoteCollection blk -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx PerasVoteCollection blk
voteCollection
noThunks Context
ctx (PerasTargetVoteWinner PerasVoteCollection blk
voteCollection ValidatedPerasCert blk
cert) =
Context
-> (PerasVoteCollection blk, ValidatedPerasCert blk)
-> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx (PerasVoteCollection blk
voteCollection, ValidatedPerasCert blk
cert)
getPerasTargetVoteStateTotalWeight :: PerasTargetVoteState blk status -> VoteWeight
getPerasTargetVoteStateTotalWeight :: forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> VoteWeight
getPerasTargetVoteStateTotalWeight = PerasVoteCollection blk -> VoteWeight
forall blk. PerasVoteCollection blk -> VoteWeight
pvcTotalWeight (PerasVoteCollection blk -> VoteWeight)
-> (PerasTargetVoteState blk status -> PerasVoteCollection blk)
-> PerasTargetVoteState blk status
-> VoteWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PerasTargetVoteState blk status -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection
getPerasTargetVoteStateBlock :: PerasTargetVoteState blk status -> Point blk
getPerasTargetVoteStateBlock :: forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> Point blk
getPerasTargetVoteStateBlock = PerasVoteTarget blk -> Point blk
forall blk. PerasVoteTarget blk -> Point blk
pvtBlock (PerasVoteTarget blk -> Point blk)
-> (PerasTargetVoteState blk status -> PerasVoteTarget blk)
-> PerasTargetVoteState blk status
-> Point blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PerasVoteCollection blk -> PerasVoteTarget blk
forall blk. PerasVoteCollection blk -> PerasVoteTarget blk
pvcTarget (PerasVoteCollection blk -> PerasVoteTarget blk)
-> (PerasTargetVoteState blk status -> PerasVoteCollection blk)
-> PerasTargetVoteState blk status
-> PerasVoteTarget blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PerasTargetVoteState blk status -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection
ptvsVoteCollection :: PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection :: forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection = \case
PerasTargetVoteCandidate PerasVoteCollection blk
voteCollection -> PerasVoteCollection blk
voteCollection
PerasTargetVoteLoser PerasVoteCollection blk
voteCollection -> PerasVoteCollection blk
voteCollection
PerasTargetVoteWinner PerasVoteCollection blk
voteCollection ValidatedPerasCert blk
_ -> PerasVoteCollection blk
voteCollection
candidateOrWinnerVoteStateSingleton ::
BlockSupportsPeras blk =>
PerasParams blk ->
WithArrivalTime (ValidatedPerasVote blk) ->
Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
candidateOrWinnerVoteStateSingleton :: forall blk.
BlockSupportsPeras blk =>
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
candidateOrWinnerVoteStateSingleton PerasParams blk
params WithArrivalTime (ValidatedPerasVote blk)
vote =
let voteCollection :: PerasVoteCollection blk
voteCollection = WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteCollection blk
forall blk.
IsPerasVote (PerasVote blk) blk =>
WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteCollection blk
perasVoteCollectionSingleton WithArrivalTime (ValidatedPerasVote blk)
vote
in case PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
forall blk.
PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
perasVoteCollectionCheckQuorum PerasParams blk
params PerasVoteCollection blk
voteCollection of
Just PerasVoteCollectionWithQuorum blk
votesWithQuorum -> do
cert <- PerasParams blk
-> PerasVoteCollectionWithQuorum blk
-> Either (PerasError blk) (ValidatedPerasCert blk)
forall blk.
BlockSupportsPeras blk =>
PerasParams blk
-> PerasVoteCollectionWithQuorum blk
-> Either (PerasError blk) (ValidatedPerasCert blk)
forgePerasCert PerasParams blk
params PerasVoteCollectionWithQuorum blk
votesWithQuorum Either (VoidPerasError blk) (ValidatedPerasCert blk)
-> (VoidPerasError blk -> UpdateRoundVoteStateError blk)
-> Either (UpdateRoundVoteStateError blk) (ValidatedPerasCert blk)
forall e a e'. Either e a -> (e -> e') -> Either e' a
`onErr` VoidPerasError blk -> UpdateRoundVoteStateError blk
PerasError blk -> UpdateRoundVoteStateError blk
forall blk. PerasError blk -> UpdateRoundVoteStateError blk
RoundVoteStateForgingCertError
pure $ BecameWinner $ PerasTargetVoteWinner voteCollection cert
Maybe (PerasVoteCollectionWithQuorum blk)
Nothing ->
PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall a. a -> Either (UpdateRoundVoteStateError blk) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk))
-> PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall a b. (a -> b) -> a -> b
$ PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk
forall blk.
PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk
RemainedCandidate (PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk)
-> PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk
forall a b. (a -> b) -> a -> b
$ PerasVoteCollection blk -> PerasTargetVoteState blk 'Candidate
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Candidate
PerasTargetVoteCandidate PerasVoteCollection blk
voteCollection
loserVoteStateSingleton ::
PerasParams blk ->
PerasTargetVoteState blk 'Winner ->
WithArrivalTime (ValidatedPerasVote blk) ->
Either (UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
loserVoteStateSingleton :: forall blk.
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
loserVoteStateSingleton PerasParams blk
params PerasTargetVoteState blk 'Winner
winnerState WithArrivalTime (ValidatedPerasVote blk)
vote =
let voteCollection :: PerasVoteCollection blk
voteCollection = WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteCollection blk
forall blk.
IsPerasVote (PerasVote blk) blk =>
WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteCollection blk
perasVoteCollectionSingleton WithArrivalTime (ValidatedPerasVote blk)
vote
in case PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
forall blk.
PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
perasVoteCollectionCheckQuorum PerasParams blk
params PerasVoteCollection blk
voteCollection of
Just PerasVoteCollectionWithQuorum blk
_ ->
UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. a -> Either a b
Left (UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser))
-> UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. (a -> b) -> a -> b
$ PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Loser -> UpdateRoundVoteStateError blk
forall blk.
PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Loser -> UpdateRoundVoteStateError blk
RoundVoteStateLoserAboveQuorum PerasTargetVoteState blk 'Winner
winnerState (PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
PerasTargetVoteLoser PerasVoteCollection blk
voteCollection)
Maybe (PerasVoteCollectionWithQuorum blk)
Nothing ->
PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. b -> Either a b
Right (PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser))
-> PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. (a -> b) -> a -> b
$ PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
PerasTargetVoteLoser PerasVoteCollection blk
voteCollection
candidateToLoser ::
PerasTargetVoteState blk 'Candidate ->
PerasTargetVoteState blk 'Loser
candidateToLoser :: forall blk.
PerasTargetVoteState blk 'Candidate
-> PerasTargetVoteState blk 'Loser
candidateToLoser (PerasTargetVoteCandidate PerasVoteCollection blk
voteCollection) =
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
PerasTargetVoteLoser PerasVoteCollection blk
voteCollection
data PerasVoteStateCandidateOrWinner blk
= RemainedCandidate (PerasTargetVoteState blk 'Candidate)
| BecameWinner (PerasTargetVoteState blk 'Winner)
updateCandidateVoteState ::
StandardHash blk =>
PerasParams blk ->
WithArrivalTime (ValidatedPerasVote blk) ->
PerasTargetVoteState blk 'Candidate ->
Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
updateCandidateVoteState :: forall blk.
StandardHash blk =>
PerasParams blk
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Candidate
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
updateCandidateVoteState PerasParams blk
params WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Candidate
oldState =
let
newVoteCollection :: PerasVoteCollection blk
newVoteCollection = WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
forall blk.
(StandardHash blk, IsPerasVote (PerasVote blk) blk) =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
perasVoteCollectionAddVote WithArrivalTime (ValidatedPerasVote blk)
vote (PerasTargetVoteState blk 'Candidate -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Candidate
oldState)
in
case PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
forall blk.
PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
perasVoteCollectionCheckQuorum PerasParams blk
params PerasVoteCollection blk
newVoteCollection of
Just PerasVoteCollectionWithQuorum blk
votesWithQuorum -> do
cert <- PerasParams blk
-> PerasVoteCollectionWithQuorum blk
-> Either (PerasError blk) (ValidatedPerasCert blk)
forall blk.
BlockSupportsPeras blk =>
PerasParams blk
-> PerasVoteCollectionWithQuorum blk
-> Either (PerasError blk) (ValidatedPerasCert blk)
forgePerasCert PerasParams blk
params PerasVoteCollectionWithQuorum blk
votesWithQuorum Either (VoidPerasError blk) (ValidatedPerasCert blk)
-> (VoidPerasError blk -> UpdateRoundVoteStateError blk)
-> Either (UpdateRoundVoteStateError blk) (ValidatedPerasCert blk)
forall e a e'. Either e a -> (e -> e') -> Either e' a
`onErr` VoidPerasError blk -> UpdateRoundVoteStateError blk
PerasError blk -> UpdateRoundVoteStateError blk
forall blk. PerasError blk -> UpdateRoundVoteStateError blk
RoundVoteStateForgingCertError
pure $ BecameWinner (PerasTargetVoteWinner newVoteCollection cert)
Maybe (PerasVoteCollectionWithQuorum blk)
Nothing -> do
PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall a. a -> Either (UpdateRoundVoteStateError blk) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk))
-> PerasVoteStateCandidateOrWinner blk
-> Either
(UpdateRoundVoteStateError blk)
(PerasVoteStateCandidateOrWinner blk)
forall a b. (a -> b) -> a -> b
$ PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk
forall blk.
PerasTargetVoteState blk 'Candidate
-> PerasVoteStateCandidateOrWinner blk
RemainedCandidate (PerasVoteCollection blk -> PerasTargetVoteState blk 'Candidate
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Candidate
PerasTargetVoteCandidate PerasVoteCollection blk
newVoteCollection)
updateLoserVoteState ::
StandardHash blk =>
PerasParams blk ->
PerasTargetVoteState blk 'Winner ->
WithArrivalTime (ValidatedPerasVote blk) ->
PerasTargetVoteState blk 'Loser ->
Either (UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
updateLoserVoteState :: forall blk.
StandardHash blk =>
PerasParams blk
-> PerasTargetVoteState blk 'Winner
-> WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
updateLoserVoteState PerasParams blk
params PerasTargetVoteState blk 'Winner
winnerState WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Loser
oldState =
Bool
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteTarget blk
forall vote blk.
IsPerasVote vote blk =>
vote -> PerasVoteTarget blk
getPerasVoteTarget WithArrivalTime (ValidatedPerasVote blk)
vote PerasVoteTarget blk -> PerasVoteTarget blk -> Bool
forall a. Eq a => a -> a -> Bool
== PerasVoteCollection blk -> PerasVoteTarget blk
forall blk. PerasVoteCollection blk -> PerasVoteTarget blk
pvcTarget (PerasTargetVoteState blk 'Loser -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Loser
oldState)) (Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser))
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. (a -> b) -> a -> b
$ do
let newVoteCollection :: PerasVoteCollection blk
newVoteCollection = WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
forall blk.
(StandardHash blk, IsPerasVote (PerasVote blk) blk) =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
perasVoteCollectionAddVote WithArrivalTime (ValidatedPerasVote blk)
vote (PerasTargetVoteState blk 'Loser -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Loser
oldState)
in case PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
forall blk.
PerasParams blk
-> PerasVoteCollection blk
-> Maybe (PerasVoteCollectionWithQuorum blk)
perasVoteCollectionCheckQuorum PerasParams blk
params PerasVoteCollection blk
newVoteCollection of
Just PerasVoteCollectionWithQuorum blk
_ ->
UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. a -> Either a b
Left (UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser))
-> UpdateRoundVoteStateError blk
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. (a -> b) -> a -> b
$ PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Loser -> UpdateRoundVoteStateError blk
forall blk.
PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Loser -> UpdateRoundVoteStateError blk
RoundVoteStateLoserAboveQuorum PerasTargetVoteState blk 'Winner
winnerState (PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
PerasTargetVoteLoser PerasVoteCollection blk
newVoteCollection)
Maybe (PerasVoteCollectionWithQuorum blk)
Nothing ->
PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. b -> Either a b
Right (PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser))
-> PerasTargetVoteState blk 'Loser
-> Either
(UpdateRoundVoteStateError blk) (PerasTargetVoteState blk 'Loser)
forall a b. (a -> b) -> a -> b
$ PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
forall blk.
PerasVoteCollection blk -> PerasTargetVoteState blk 'Loser
PerasTargetVoteLoser PerasVoteCollection blk
newVoteCollection
updateWinnerVoteState ::
( StandardHash blk
, IsPerasVote (PerasVote blk) blk
) =>
WithArrivalTime (ValidatedPerasVote blk) ->
PerasTargetVoteState blk 'Winner ->
PerasTargetVoteState blk 'Winner
updateWinnerVoteState :: forall blk.
(StandardHash blk, IsPerasVote (PerasVote blk) blk) =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner
updateWinnerVoteState WithArrivalTime (ValidatedPerasVote blk)
vote PerasTargetVoteState blk 'Winner
oldState =
Bool
-> PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (WithArrivalTime (ValidatedPerasVote blk) -> PerasVoteTarget blk
forall vote blk.
IsPerasVote vote blk =>
vote -> PerasVoteTarget blk
getPerasVoteTarget WithArrivalTime (ValidatedPerasVote blk)
vote PerasVoteTarget blk -> PerasVoteTarget blk -> Bool
forall a. Eq a => a -> a -> Bool
== PerasVoteCollection blk -> PerasVoteTarget blk
forall blk. PerasVoteCollection blk -> PerasVoteTarget blk
pvcTarget (PerasTargetVoteState blk 'Winner -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Winner
oldState)) (PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner)
-> PerasTargetVoteState blk 'Winner
-> PerasTargetVoteState blk 'Winner
forall a b. (a -> b) -> a -> b
$ do
let newVoteCollection :: PerasVoteCollection blk
newVoteCollection = WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
forall blk.
(StandardHash blk, IsPerasVote (PerasVote blk) blk) =>
WithArrivalTime (ValidatedPerasVote blk)
-> PerasVoteCollection blk -> PerasVoteCollection blk
perasVoteCollectionAddVote WithArrivalTime (ValidatedPerasVote blk)
vote (PerasTargetVoteState blk 'Winner -> PerasVoteCollection blk
forall blk (status :: PerasTargetVoteStatus).
PerasTargetVoteState blk status -> PerasVoteCollection blk
ptvsVoteCollection PerasTargetVoteState blk 'Winner
oldState)
(PerasTargetVoteWinner PerasVoteCollection blk
_ ValidatedPerasCert blk
cert) = PerasTargetVoteState blk 'Winner
oldState
in PerasVoteCollection blk
-> ValidatedPerasCert blk -> PerasTargetVoteState blk 'Winner
forall blk.
PerasVoteCollection blk
-> ValidatedPerasCert blk -> PerasTargetVoteState blk 'Winner
PerasTargetVoteWinner PerasVoteCollection blk
newVoteCollection ValidatedPerasCert blk
cert
onErr :: Either e a -> (e -> e') -> Either e' a
onErr :: forall e a e'. Either e a -> (e -> e') -> Either e' a
onErr (Left e
err) e -> e'
f = e' -> Either e' a
forall a b. a -> Either a b
Left (e -> e'
f e
err)
onErr (Right a
val) e -> e'
_ = a -> Either e' a
forall a b. b -> Either a b
Right a
val