{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE EmptyDataDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Mocked crypto for Peras.
--
-- This crypto scheme doesn't use any real cryptography, and should only be used
-- for testing purposes. The only possible error thrown by this implementation
-- is when a seat index is out of bounds for a given voting committee.
module Ouroboros.Consensus.Peras.Crypto.Mock
  ( -- * Mocked crypto for Peras
    MockPerasVotingCommitteeScheme
  , MockPerasCrypto
  , VotingCommittee (..)
  , VotingCommitteeInput (..)
  , VotingCommitteeError (..)
  , EligibilityWitness (..)
  , Vote (..)
  , Cert (..)

    -- * Helpers
  , seatIndexToInt
  , unsafeIntToSeatIndex
  , getEligibilityWitness
  ) where

import Cardano.Binary
  ( FromCBOR (..)
  , ToCBOR (..)
  , decodeListLenOf
  , encodeListLen
  )
import Cardano.Prelude (Bifunctor (second))
import Control.Exception.Base (Exception)
import Data.Either.Extra (maybeToEither)
import qualified Data.List as List
import Data.List.Extra ((!?))
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Set.NonEmpty as NESet
import Data.Typeable (Typeable)
import Data.Word (Word16)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)
import Ouroboros.Consensus.Block.Abstract (Point, StandardHash)
import Ouroboros.Consensus.Committee.Class
  ( CryptoSupportsVotingCommittee (..)
  , VotingCommittee
  , getElectionIdFromVotes
  , getRawVotes
  , getVoteCandidateFromVotes
  )
import Ouroboros.Consensus.Committee.Crypto
  ( CryptoSupportsAggregateVoteSigning (..)
  , CryptoSupportsVoteSigning (..)
  , ElectionId
  , PrivateKey
  , PublicKey
  , VoteCandidate
  )
import Ouroboros.Consensus.Committee.Types (LedgerStake (..), PoolId)
import Ouroboros.Consensus.Peras.Cert.Mock (MockPerasCert (..))
import Ouroboros.Consensus.Peras.Types
  ( PerasRoundNo
  , PerasSeatIndex (..)
  , VoteWeight (..)
  )
import Ouroboros.Consensus.Peras.Vote.Mock (MockPerasVote (..))
import Ouroboros.Consensus.Peras.Voting.Adapter
  ( PerasCertCompatibleWithVotingCommittee (..)
  , PerasVoteCompatibleWithVotingCommittee (..)
  )

-- * | A mock crypto scheme for Peras.

-- | A mock crypto scheme for Peras
data MockPerasCrypto blk
  deriving (Int -> MockPerasCrypto blk -> ShowS
[MockPerasCrypto blk] -> ShowS
MockPerasCrypto blk -> [Char]
(Int -> MockPerasCrypto blk -> ShowS)
-> (MockPerasCrypto blk -> [Char])
-> ([MockPerasCrypto blk] -> ShowS)
-> Show (MockPerasCrypto blk)
forall blk. Int -> MockPerasCrypto blk -> ShowS
forall blk. [MockPerasCrypto blk] -> ShowS
forall blk. MockPerasCrypto blk -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall blk. Int -> MockPerasCrypto blk -> ShowS
showsPrec :: Int -> MockPerasCrypto blk -> ShowS
$cshow :: forall blk. MockPerasCrypto blk -> [Char]
show :: MockPerasCrypto blk -> [Char]
$cshowList :: forall blk. [MockPerasCrypto blk] -> ShowS
showList :: [MockPerasCrypto blk] -> ShowS
Show, MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
(MockPerasCrypto blk -> MockPerasCrypto blk -> Bool)
-> (MockPerasCrypto blk -> MockPerasCrypto blk -> Bool)
-> Eq (MockPerasCrypto blk)
forall blk. MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall blk. MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
== :: MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
$c/= :: forall blk. MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
/= :: MockPerasCrypto blk -> MockPerasCrypto blk -> Bool
Eq, (forall x. MockPerasCrypto blk -> Rep (MockPerasCrypto blk) x)
-> (forall x. Rep (MockPerasCrypto blk) x -> MockPerasCrypto blk)
-> Generic (MockPerasCrypto blk)
forall x. Rep (MockPerasCrypto blk) x -> MockPerasCrypto blk
forall x. MockPerasCrypto blk -> Rep (MockPerasCrypto blk) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall blk x. Rep (MockPerasCrypto blk) x -> MockPerasCrypto blk
forall blk x. MockPerasCrypto blk -> Rep (MockPerasCrypto blk) x
$cfrom :: forall blk x. MockPerasCrypto blk -> Rep (MockPerasCrypto blk) x
from :: forall x. MockPerasCrypto blk -> Rep (MockPerasCrypto blk) x
$cto :: forall blk x. Rep (MockPerasCrypto blk) x -> MockPerasCrypto blk
to :: forall x. Rep (MockPerasCrypto blk) x -> MockPerasCrypto blk
Generic, Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
Proxy (MockPerasCrypto blk) -> [Char]
(Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo))
-> (Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo))
-> (Proxy (MockPerasCrypto blk) -> [Char])
-> NoThunks (MockPerasCrypto blk)
forall blk. Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
forall blk. Proxy (MockPerasCrypto blk) -> [Char]
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> [Char])
-> NoThunks a
$cnoThunks :: forall blk. Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
noThunks :: Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall blk. Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> MockPerasCrypto blk -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall blk. Proxy (MockPerasCrypto blk) -> [Char]
showTypeOf :: Proxy (MockPerasCrypto blk) -> [Char]
NoThunks)

type instance ElectionId (MockPerasCrypto blk) = PerasRoundNo
type instance VoteCandidate (MockPerasCrypto blk) = Point blk

type instance PrivateKey (MockPerasCrypto blk) = ()
type instance PublicKey (MockPerasCrypto blk) = ()

instance CryptoSupportsVoteSigning (MockPerasCrypto blk) where
  type VoteSigningKey (MockPerasCrypto blk) = ()
  type VoteVerificationKey (MockPerasCrypto blk) = ()
  data VoteSignature (MockPerasCrypto blk) = MockVoteSignature
  getVoteSigningKey :: Proxy (MockPerasCrypto blk)
-> PrivateKey (MockPerasCrypto blk)
-> VoteSigningKey (MockPerasCrypto blk)
getVoteSigningKey Proxy (MockPerasCrypto blk)
_proxy PrivateKey (MockPerasCrypto blk)
privateKey = VoteSigningKey (MockPerasCrypto blk)
PrivateKey (MockPerasCrypto blk)
privateKey
  getVoteVerificationKey :: Proxy (MockPerasCrypto blk)
-> PublicKey (MockPerasCrypto blk)
-> VoteVerificationKey (MockPerasCrypto blk)
getVoteVerificationKey Proxy (MockPerasCrypto blk)
_proxy PublicKey (MockPerasCrypto blk)
publicKey = VoteVerificationKey (MockPerasCrypto blk)
PublicKey (MockPerasCrypto blk)
publicKey
  signVote :: VoteSigningKey (MockPerasCrypto blk)
-> ElectionId (MockPerasCrypto blk)
-> VoteCandidate (MockPerasCrypto blk)
-> VoteSignature (MockPerasCrypto blk)
signVote VoteSigningKey (MockPerasCrypto blk)
_ ElectionId (MockPerasCrypto blk)
_ VoteCandidate (MockPerasCrypto blk)
_ = VoteSignature (MockPerasCrypto blk)
forall blk. VoteSignature (MockPerasCrypto blk)
MockVoteSignature
  verifyVoteSignature :: VoteVerificationKey (MockPerasCrypto blk)
-> ElectionId (MockPerasCrypto blk)
-> VoteCandidate (MockPerasCrypto blk)
-> VoteSignature (MockPerasCrypto blk)
-> Either [Char] ()
verifyVoteSignature VoteVerificationKey (MockPerasCrypto blk)
_ ElectionId (MockPerasCrypto blk)
_ VoteCandidate (MockPerasCrypto blk)
_ VoteSignature (MockPerasCrypto blk)
_ = () -> Either [Char] ()
forall a b. b -> Either a b
Right ()

instance CryptoSupportsAggregateVoteSigning (MockPerasCrypto blk) where
  type AggregateVoteSignature (MockPerasCrypto blk) = ()
  type AggregateVoteVerificationKey (MockPerasCrypto blk) = ()
  aggregateVoteSignatures :: Proxy (MockPerasCrypto blk)
-> NE [VoteSignature (MockPerasCrypto blk)]
-> Either [Char] (AggregateVoteSignature (MockPerasCrypto blk))
aggregateVoteSignatures Proxy (MockPerasCrypto blk)
_ NE [VoteSignature (MockPerasCrypto blk)]
_ = () -> Either [Char] ()
forall a b. b -> Either a b
Right ()
  verifyAggregateVoteSignature :: Proxy (MockPerasCrypto blk)
-> AggregateVoteVerificationKey (MockPerasCrypto blk)
-> ElectionId (MockPerasCrypto blk)
-> VoteCandidate (MockPerasCrypto blk)
-> AggregateVoteSignature (MockPerasCrypto blk)
-> Either [Char] ()
verifyAggregateVoteSignature Proxy (MockPerasCrypto blk)
_ AggregateVoteVerificationKey (MockPerasCrypto blk)
_ ElectionId (MockPerasCrypto blk)
_ VoteCandidate (MockPerasCrypto blk)
_ AggregateVoteSignature (MockPerasCrypto blk)
_ = () -> Either [Char] ()
forall a b. b -> Either a b
Right ()
  aggregateVoteVerificationKeys :: Proxy (MockPerasCrypto blk)
-> NE [VoteVerificationKey (MockPerasCrypto blk)]
-> Either
     [Char] (AggregateVoteVerificationKey (MockPerasCrypto blk))
aggregateVoteVerificationKeys Proxy (MockPerasCrypto blk)
_ NE [VoteVerificationKey (MockPerasCrypto blk)]
_ = () -> Either [Char] ()
forall a b. b -> Either a b
Right ()

-- | A mock voting committee scheme for Peras
data MockPerasVotingCommitteeScheme blk
  deriving (Int -> MockPerasVotingCommitteeScheme blk -> ShowS
[MockPerasVotingCommitteeScheme blk] -> ShowS
MockPerasVotingCommitteeScheme blk -> [Char]
(Int -> MockPerasVotingCommitteeScheme blk -> ShowS)
-> (MockPerasVotingCommitteeScheme blk -> [Char])
-> ([MockPerasVotingCommitteeScheme blk] -> ShowS)
-> Show (MockPerasVotingCommitteeScheme blk)
forall blk. Int -> MockPerasVotingCommitteeScheme blk -> ShowS
forall blk. [MockPerasVotingCommitteeScheme blk] -> ShowS
forall blk. MockPerasVotingCommitteeScheme blk -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall blk. Int -> MockPerasVotingCommitteeScheme blk -> ShowS
showsPrec :: Int -> MockPerasVotingCommitteeScheme blk -> ShowS
$cshow :: forall blk. MockPerasVotingCommitteeScheme blk -> [Char]
show :: MockPerasVotingCommitteeScheme blk -> [Char]
$cshowList :: forall blk. [MockPerasVotingCommitteeScheme blk] -> ShowS
showList :: [MockPerasVotingCommitteeScheme blk] -> ShowS
Show, MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
(MockPerasVotingCommitteeScheme blk
 -> MockPerasVotingCommitteeScheme blk -> Bool)
-> (MockPerasVotingCommitteeScheme blk
    -> MockPerasVotingCommitteeScheme blk -> Bool)
-> Eq (MockPerasVotingCommitteeScheme blk)
forall blk.
MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall blk.
MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
== :: MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
$c/= :: forall blk.
MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
/= :: MockPerasVotingCommitteeScheme blk
-> MockPerasVotingCommitteeScheme blk -> Bool
Eq, (forall x.
 MockPerasVotingCommitteeScheme blk
 -> Rep (MockPerasVotingCommitteeScheme blk) x)
-> (forall x.
    Rep (MockPerasVotingCommitteeScheme blk) x
    -> MockPerasVotingCommitteeScheme blk)
-> Generic (MockPerasVotingCommitteeScheme blk)
forall x.
Rep (MockPerasVotingCommitteeScheme blk) x
-> MockPerasVotingCommitteeScheme blk
forall x.
MockPerasVotingCommitteeScheme blk
-> Rep (MockPerasVotingCommitteeScheme blk) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall blk x.
Rep (MockPerasVotingCommitteeScheme blk) x
-> MockPerasVotingCommitteeScheme blk
forall blk x.
MockPerasVotingCommitteeScheme blk
-> Rep (MockPerasVotingCommitteeScheme blk) x
$cfrom :: forall blk x.
MockPerasVotingCommitteeScheme blk
-> Rep (MockPerasVotingCommitteeScheme blk) x
from :: forall x.
MockPerasVotingCommitteeScheme blk
-> Rep (MockPerasVotingCommitteeScheme blk) x
$cto :: forall blk x.
Rep (MockPerasVotingCommitteeScheme blk) x
-> MockPerasVotingCommitteeScheme blk
to :: forall x.
Rep (MockPerasVotingCommitteeScheme blk) x
-> MockPerasVotingCommitteeScheme blk
Generic, Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
Proxy (MockPerasVotingCommitteeScheme blk) -> [Char]
(Context
 -> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo))
-> (Context
    -> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo))
-> (Proxy (MockPerasVotingCommitteeScheme blk) -> [Char])
-> NoThunks (MockPerasVotingCommitteeScheme blk)
forall blk.
Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
forall blk. Proxy (MockPerasVotingCommitteeScheme blk) -> [Char]
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> [Char])
-> NoThunks a
$cnoThunks :: forall blk.
Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
noThunks :: Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall blk.
Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
wNoThunks :: Context
-> MockPerasVotingCommitteeScheme blk -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall blk. Proxy (MockPerasVotingCommitteeScheme blk) -> [Char]
showTypeOf :: Proxy (MockPerasVotingCommitteeScheme blk) -> [Char]
NoThunks)

newtype instance VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
  = MockPerasVotingCommittee
  { -- Stake distribution
    forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> NonEmpty (PoolId, VoteWeight)
weightDistr :: NonEmpty (PoolId, VoteWeight)
  }

instance
  ( Ord (ElectionId crypto)
  , ElectionId crypto ~ PerasRoundNo
  , VoteCandidate crypto ~ Point blk
  , CryptoSupportsAggregateVoteSigning crypto
  ) =>
  CryptoSupportsVotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
  where
  newtype VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk)
    = MockPerasVotingCommitteeInput (NonEmpty (PoolId, LedgerStake))

  newtype VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
    = -- Seat index is out of bounds for the voting committee
      MissingSeatIndex PerasSeatIndex

  data EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
    = MockPerasVotingCommitteeSchemeMember
        !PerasSeatIndex
        !VoteWeight

  newtype Vote crypto (MockPerasVotingCommitteeScheme blk)
    = MockPerasVotingCommitteeSchemeVote (MockPerasVote blk)

  newtype Cert crypto (MockPerasVotingCommitteeScheme blk)
    = MockPerasVotingCommitteeSchemeCert (MockPerasCert blk)

  mkVotingCommittee :: VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))
mkVotingCommittee (MockPerasVotingCommitteeInput NonEmpty (PoolId, LedgerStake)
stakeDistr) =
    VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))
forall a b. b -> Either a b
Right
      MockPerasVotingCommittee
        { weightDistr :: NonEmpty (PoolId, VoteWeight)
weightDistr = (LedgerStake -> VoteWeight)
-> (PoolId, LedgerStake) -> (PoolId, VoteWeight)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second LedgerStake -> VoteWeight
normalize ((PoolId, LedgerStake) -> (PoolId, VoteWeight))
-> NonEmpty (PoolId, LedgerStake) -> NonEmpty (PoolId, VoteWeight)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (PoolId, LedgerStake)
stakeDistr
        }
   where
    LedgerStake Ratio Integer
totalStake = NonEmpty LedgerStake -> LedgerStake
forall a. Num a => NonEmpty a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((PoolId, LedgerStake) -> LedgerStake
forall a b. (a, b) -> b
snd ((PoolId, LedgerStake) -> LedgerStake)
-> NonEmpty (PoolId, LedgerStake) -> NonEmpty LedgerStake
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (PoolId, LedgerStake)
stakeDistr)
    normalize :: LedgerStake -> VoteWeight
normalize (LedgerStake Ratio Integer
stake)
      | Ratio Integer
totalStake Ratio Integer -> Ratio Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Ratio Integer
0 = VoteWeight
0
      | Bool
otherwise = Ratio Integer -> VoteWeight
VoteWeight (Ratio Integer
stake Ratio Integer -> Ratio Integer -> Ratio Integer
forall a. Fractional a => a -> a -> a
/ Ratio Integer
totalStake)

  checkShouldVote :: VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> PoolId
-> PrivateKey crypto
-> ElectionId crypto
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Maybe
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
checkShouldVote MockPerasVotingCommittee{NonEmpty (PoolId, VoteWeight)
weightDistr :: forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> NonEmpty (PoolId, VoteWeight)
weightDistr :: NonEmpty (PoolId, VoteWeight)
weightDistr} PoolId
poolId PrivateKey crypto
_ ElectionId crypto
_ =
    case ((PoolId, VoteWeight) -> Bool)
-> NonEmpty (PoolId, VoteWeight)
-> Maybe (Int, (PoolId, VoteWeight))
forall a. (a -> Bool) -> NonEmpty a -> Maybe (Int, a)
findWithIndex (\(PoolId
pid, VoteWeight
_) -> PoolId
pid PoolId -> PoolId -> Bool
forall a. Eq a => a -> a -> Bool
== PoolId
poolId) NonEmpty (PoolId, VoteWeight)
weightDistr of
      Just (Int
rawIndex, (PoolId
_pid, VoteWeight
voteWeight)) ->
        Maybe
  (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Maybe
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
forall a b. b -> Either a b
Right (Maybe
   (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
 -> Either
      (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
      (Maybe
         (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))))
-> (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
    -> Maybe
         (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Maybe
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a. a -> Maybe a
Just (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
 -> Either
      (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
      (Maybe
         (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))))
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Maybe
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
forall a b. (a -> b) -> a -> b
$
          PerasSeatIndex
-> VoteWeight
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
PerasSeatIndex
-> VoteWeight
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeMember
            (Int -> PerasSeatIndex
unsafeIntToSeatIndex Int
rawIndex)
            VoteWeight
voteWeight
      Maybe (Int, (PoolId, VoteWeight))
_ ->
        Maybe
  (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Maybe
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
forall a b. b -> Either a b
Right Maybe
  (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a. Maybe a
Nothing
   where
    findWithIndex :: (a -> Bool) -> NonEmpty a -> Maybe (Int, a)
    findWithIndex :: forall a. (a -> Bool) -> NonEmpty a -> Maybe (Int, a)
findWithIndex a -> Bool
p NonEmpty a
xs = ((Int, a) -> Bool) -> [(Int, a)] -> Maybe (Int, a)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (a -> Bool
p (a -> Bool) -> ((Int, a) -> a) -> (Int, a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, a) -> a
forall a b. (a, b) -> b
snd) ([Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty a
xs))

  forgeVote :: EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> PrivateKey crypto
-> ElectionId crypto
-> VoteCandidate crypto
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
forgeVote (MockPerasVotingCommitteeSchemeMember PerasSeatIndex
seatIndex VoteWeight
_) PrivateKey crypto
_ ElectionId crypto
roundNo VoteCandidate crypto
block =
    MockPerasVote blk
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
MockPerasVote blk
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeVote (MockPerasVote blk
 -> Vote crypto (MockPerasVotingCommitteeScheme blk))
-> MockPerasVote blk
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
forall a b. (a -> b) -> a -> b
$
      MockPerasVote
        { mockVoteRound :: PerasRoundNo
mockVoteRound = ElectionId crypto
PerasRoundNo
roundNo
        , mockVoteBlock :: Point blk
mockVoteBlock = VoteCandidate crypto
Point blk
block
        , mockVoteSeatIndex :: PerasSeatIndex
mockVoteSeatIndex = PerasSeatIndex
seatIndex
        }

  verifyVote :: VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
verifyVote
    MockPerasVotingCommittee{NonEmpty (PoolId, VoteWeight)
weightDistr :: forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> NonEmpty (PoolId, VoteWeight)
weightDistr :: NonEmpty (PoolId, VoteWeight)
weightDistr}
    (MockPerasVotingCommitteeSchemeVote MockPerasVote blk
mockVote) =
      case NonEmpty (PoolId, VoteWeight) -> [(PoolId, VoteWeight)]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty (PoolId, VoteWeight)
weightDistr [(PoolId, VoteWeight)] -> Int -> Maybe (PoolId, VoteWeight)
forall a. [a] -> Int -> Maybe a
!? PerasSeatIndex -> Int
seatIndexToInt PerasSeatIndex
seatIndex of
        Just (PoolId
_pid, VoteWeight
voteWeight) ->
          EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a b. b -> Either a b
Right (PerasSeatIndex
-> VoteWeight
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
PerasSeatIndex
-> VoteWeight
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeMember PerasSeatIndex
seatIndex VoteWeight
voteWeight)
        Maybe (PoolId, VoteWeight)
_ ->
          VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a b. a -> Either a b
Left (PerasSeatIndex
-> VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
PerasSeatIndex
-> VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
MissingSeatIndex PerasSeatIndex
seatIndex)
     where
      seatIndex :: PerasSeatIndex
seatIndex = MockPerasVote blk -> PerasSeatIndex
forall blk. MockPerasVote blk -> PerasSeatIndex
mockVoteSeatIndex MockPerasVote blk
mockVote

  eligiblePartyVoteWeight :: VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> VoteWeight
eligiblePartyVoteWeight
    VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
_
    (MockPerasVotingCommitteeSchemeMember PerasSeatIndex
_seatIndex VoteWeight
voteWeight) =
      VoteWeight
voteWeight

  forgeCert :: UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Cert crypto (MockPerasVotingCommitteeScheme blk))
forgeCert UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
uniqueVoteWithSameTarget = do
    Cert crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Cert crypto (MockPerasVotingCommitteeScheme blk))
forall a.
a
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cert crypto (MockPerasVotingCommitteeScheme blk)
 -> Either
      (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
      (Cert crypto (MockPerasVotingCommitteeScheme blk)))
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (Cert crypto (MockPerasVotingCommitteeScheme blk))
forall a b. (a -> b) -> a -> b
$
      MockPerasCert blk
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
MockPerasCert blk
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeCert (MockPerasCert blk
 -> Cert crypto (MockPerasVotingCommitteeScheme blk))
-> MockPerasCert blk
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
forall a b. (a -> b) -> a -> b
$
        MockPerasCert
          { mockCertRound :: PerasRoundNo
mockCertRound = ElectionId crypto
PerasRoundNo
roundNo
          , mockCertBlock :: Point blk
mockCertBlock = VoteCandidate crypto
Point blk
block
          , mockCertVoters :: NE (Set PerasSeatIndex)
mockCertVoters = NESet PerasSeatIndex
NE (Set PerasSeatIndex)
voters
          }
   where
    roundNo :: ElectionId crypto
roundNo = UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
-> ElectionId crypto
forall crypto committee.
UniqueVotesWithSameTarget crypto committee -> ElectionId crypto
getElectionIdFromVotes UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
uniqueVoteWithSameTarget
    block :: VoteCandidate crypto
block = UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
-> VoteCandidate crypto
forall crypto committee.
UniqueVotesWithSameTarget crypto committee -> VoteCandidate crypto
getVoteCandidateFromVotes UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
uniqueVoteWithSameTarget
    rawVotes :: NE [Vote crypto (MockPerasVotingCommitteeScheme blk)]
rawVotes = UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
-> NE [Vote crypto (MockPerasVotingCommitteeScheme blk)]
forall crypto committee.
UniqueVotesWithSameTarget crypto committee
-> NE [Vote crypto committee]
getRawVotes UniqueVotesWithSameTarget
  crypto (MockPerasVotingCommitteeScheme blk)
uniqueVoteWithSameTarget
    voters :: NESet PerasSeatIndex
voters = NonEmpty PerasSeatIndex -> NESet PerasSeatIndex
forall a. Ord a => NonEmpty a -> NESet a
NESet.fromList (Vote crypto (MockPerasVotingCommitteeScheme blk) -> PerasSeatIndex
forall {crypto} {blk}.
Vote crypto (MockPerasVotingCommitteeScheme blk) -> PerasSeatIndex
getSeatIndex (Vote crypto (MockPerasVotingCommitteeScheme blk)
 -> PerasSeatIndex)
-> NonEmpty (Vote crypto (MockPerasVotingCommitteeScheme blk))
-> NonEmpty PerasSeatIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Vote crypto (MockPerasVotingCommitteeScheme blk))
NE [Vote crypto (MockPerasVotingCommitteeScheme blk)]
rawVotes)
    getSeatIndex :: Vote crypto (MockPerasVotingCommitteeScheme blk) -> PerasSeatIndex
getSeatIndex (MockPerasVotingCommitteeSchemeVote MockPerasVote blk
mockVote) =
      MockPerasVote blk -> PerasSeatIndex
forall blk. MockPerasVote blk -> PerasSeatIndex
mockVoteSeatIndex MockPerasVote blk
mockVote

  verifyCert :: VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (NE
        [EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)])
verifyCert VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
committee (MockPerasVotingCommitteeSchemeCert MockPerasCert blk
mockCert) =
    (PerasSeatIndex
 -> Either
      (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
      (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
-> NonEmpty PerasSeatIndex
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (NonEmpty
        (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse PerasSeatIndex
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
getProof NonEmpty PerasSeatIndex
voterList
   where
    voterList :: NonEmpty PerasSeatIndex
voterList = NESet PerasSeatIndex -> NonEmpty PerasSeatIndex
forall a. NESet a -> NonEmpty a
NESet.toList (MockPerasCert blk -> NE (Set PerasSeatIndex)
forall blk. MockPerasCert blk -> NE (Set PerasSeatIndex)
mockCertVoters MockPerasCert blk
mockCert)
    getProof :: PerasSeatIndex
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
getProof PerasSeatIndex
seatIndex =
      VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a b. a -> Maybe b -> Either a b
maybeToEither (PerasSeatIndex
-> VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
PerasSeatIndex
-> VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk)
MissingSeatIndex PerasSeatIndex
seatIndex) (Maybe
   (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
 -> Either
      (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
      (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)))
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
-> Either
     (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall a b. (a -> b) -> a -> b
$
        VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> PerasSeatIndex
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> PerasSeatIndex
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
getEligibilityWitness VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
committee PerasSeatIndex
seatIndex

  voteTarget :: Vote crypto (MockPerasVotingCommitteeScheme blk)
-> (ElectionId crypto, VoteCandidate crypto)
voteTarget
    ( MockPerasVotingCommitteeSchemeVote
        MockPerasVote{PerasRoundNo
mockVoteRound :: forall blk. MockPerasVote blk -> PerasRoundNo
mockVoteRound :: PerasRoundNo
mockVoteRound, Point blk
mockVoteBlock :: forall blk. MockPerasVote blk -> Point blk
mockVoteBlock :: Point blk
mockVoteBlock}
      ) =
      (ElectionId crypto
PerasRoundNo
mockVoteRound, VoteCandidate crypto
Point blk
mockVoteBlock)

  compareVotesById :: Vote crypto (MockPerasVotingCommitteeScheme blk)
-> Vote crypto (MockPerasVotingCommitteeScheme blk) -> Ordering
compareVotesById
    ( MockPerasVotingCommitteeSchemeVote
        MockPerasVote
          { mockVoteRound :: forall blk. MockPerasVote blk -> PerasRoundNo
mockVoteRound = PerasRoundNo
mockVoteRound1
          , mockVoteSeatIndex :: forall blk. MockPerasVote blk -> PerasSeatIndex
mockVoteSeatIndex = PerasSeatIndex
mockVoteSeatIndex1
          }
      )
    ( MockPerasVotingCommitteeSchemeVote
        MockPerasVote
          { mockVoteRound :: forall blk. MockPerasVote blk -> PerasRoundNo
mockVoteRound = PerasRoundNo
mockVoteRound2
          , mockVoteSeatIndex :: forall blk. MockPerasVote blk -> PerasSeatIndex
mockVoteSeatIndex = PerasSeatIndex
mockVoteSeatIndex2
          }
      ) =
      (PerasRoundNo, PerasSeatIndex)
-> (PerasRoundNo, PerasSeatIndex) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare
        (PerasRoundNo
mockVoteRound1, PerasSeatIndex
mockVoteSeatIndex1)
        (PerasRoundNo
mockVoteRound2, PerasSeatIndex
mockVoteSeatIndex2)

deriving newtype instance
  Show (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Eq (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  NoThunks (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Generic (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))

deriving instance
  Show (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))
deriving instance
  Eq (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  NoThunks (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Generic (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  Show (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Eq (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  NoThunks (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Generic (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))
deriving anyclass instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  Exception (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  StandardHash blk =>
  Show (Vote crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  StandardHash blk =>
  Eq (Vote crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  StandardHash blk =>
  NoThunks (Vote crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Generic (Vote crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  StandardHash blk =>
  Show (Cert crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  StandardHash blk =>
  Eq (Cert crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  StandardHash blk =>
  NoThunks (Cert crypto (MockPerasVotingCommitteeScheme blk))
deriving newtype instance
  Generic (Cert crypto (MockPerasVotingCommitteeScheme blk))

deriving instance
  Show (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
deriving instance
  Eq (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
deriving instance
  NoThunks (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
deriving instance
  Generic (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))

instance
  PerasVoteCompatibleWithVotingCommittee
    (MockPerasVote blk)
    (MockPerasCrypto blk)
    (MockPerasVotingCommitteeScheme blk)
  where
  toPerasVote :: Vote (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
-> Either PerasConversionError (MockPerasVote blk)
toPerasVote (MockPerasVotingCommitteeSchemeVote MockPerasVote blk
mockVote) =
    MockPerasVote blk
-> Either PerasConversionError (MockPerasVote blk)
forall a b. b -> Either a b
Right MockPerasVote blk
mockVote
  fromPerasVote :: MockPerasVote blk
-> Either
     PerasConversionError
     (Vote (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk))
fromPerasVote MockPerasVote blk
mockVote =
    Vote (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
-> Either
     PerasConversionError
     (Vote (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk))
forall a b. b -> Either a b
Right (MockPerasVote blk
-> Vote (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
MockPerasVote blk
-> Vote crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeVote MockPerasVote blk
mockVote)

instance
  PerasCertCompatibleWithVotingCommittee
    (MockPerasCert blk)
    (MockPerasCrypto blk)
    (MockPerasVotingCommitteeScheme blk)
  where
  toPerasCert :: Cert (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
-> Either PerasConversionError (MockPerasCert blk)
toPerasCert (MockPerasVotingCommitteeSchemeCert MockPerasCert blk
mockCert) =
    MockPerasCert blk
-> Either PerasConversionError (MockPerasCert blk)
forall a b. b -> Either a b
Right MockPerasCert blk
mockCert
  fromPerasCert :: MockPerasCert blk
-> Either
     PerasConversionError
     (Cert (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk))
fromPerasCert MockPerasCert blk
mockCert =
    Cert (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
-> Either
     PerasConversionError
     (Cert (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk))
forall a b. b -> Either a b
Right (MockPerasCert blk
-> Cert (MockPerasCrypto blk) (MockPerasVotingCommitteeScheme blk)
forall crypto blk.
MockPerasCert blk
-> Cert crypto (MockPerasVotingCommitteeScheme blk)
MockPerasVotingCommitteeSchemeCert MockPerasCert blk
mockCert)

-- * FromCBOR / ToCBOR instances

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  FromCBOR (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  ToCBOR (VotingCommittee crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  FromCBOR (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  ToCBOR (VotingCommitteeInput crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  FromCBOR (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  ToCBOR (VotingCommitteeError crypto (MockPerasVotingCommitteeScheme blk))

instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  FromCBOR (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
  where
  fromCBOR :: forall s.
Decoder
  s (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
fromCBOR = do
    Int -> Decoder s ()
forall s. Int -> Decoder s ()
decodeListLenOf Int
2
    seatIndex <- Decoder s PerasSeatIndex
forall s. Decoder s PerasSeatIndex
forall a s. FromCBOR a => Decoder s a
fromCBOR
    voteWeight <- fromCBOR
    pure (MockPerasVotingCommitteeSchemeMember seatIndex voteWeight)

instance
  ( Typeable crypto
  , Typeable blk
  ) =>
  ToCBOR (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
  where
  toCBOR :: EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk)
-> Encoding
toCBOR (MockPerasVotingCommitteeSchemeMember PerasSeatIndex
seatIndex VoteWeight
voteWeight) =
    Word -> Encoding
encodeListLen Word
2
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> PerasSeatIndex -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR PerasSeatIndex
seatIndex
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> VoteWeight -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR VoteWeight
voteWeight

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  , FromCBOR (Point blk)
  ) =>
  FromCBOR (Vote crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  , ToCBOR (Point blk)
  ) =>
  ToCBOR (Vote crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  , FromCBOR (Point blk)
  ) =>
  FromCBOR (Cert crypto (MockPerasVotingCommitteeScheme blk))

deriving newtype instance
  ( Typeable crypto
  , Typeable blk
  , ToCBOR (Point blk)
  ) =>
  ToCBOR (Cert crypto (MockPerasVotingCommitteeScheme blk))

-- * Helpers

seatIndexToInt :: PerasSeatIndex -> Int
seatIndexToInt :: PerasSeatIndex -> Int
seatIndexToInt (PerasSeatIndex Word16
seatIndex) =
  forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Int Word16
seatIndex

unsafeIntToSeatIndex :: Int -> PerasSeatIndex
unsafeIntToSeatIndex :: Int -> PerasSeatIndex
unsafeIntToSeatIndex Int
int
  | Int
int Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
int Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word16 @Int Word16
forall a. Bounded a => a
maxBound =
      Word16 -> PerasSeatIndex
PerasSeatIndex (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Int @Word16 Int
int)
  | Bool
otherwise =
      [Char] -> PerasSeatIndex
forall a. HasCallStack => [Char] -> a
error ([Char] -> PerasSeatIndex) -> [Char] -> PerasSeatIndex
forall a b. (a -> b) -> a -> b
$ [Char]
"unsafeIntToSeatIndex: Int out of bounds for PerasSeatIndex: " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
int

getEligibilityWitness ::
  VotingCommittee crypto (MockPerasVotingCommitteeScheme blk) ->
  PerasSeatIndex ->
  Maybe (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
getEligibilityWitness :: forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> PerasSeatIndex
-> Maybe
     (EligibilityWitness crypto (MockPerasVotingCommitteeScheme blk))
getEligibilityWitness MockPerasVotingCommittee{NonEmpty (PoolId, VoteWeight)
weightDistr :: forall crypto blk.
VotingCommittee crypto (MockPerasVotingCommitteeScheme blk)
-> NonEmpty (PoolId, VoteWeight)
weightDistr :: NonEmpty (PoolId, VoteWeight)
weightDistr} PerasSeatIndex
seatIndex = do
  (_poolId, voteWeight) <- NonEmpty (PoolId, VoteWeight) -> [(PoolId, VoteWeight)]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty (PoolId, VoteWeight)
weightDistr [(PoolId, VoteWeight)] -> Int -> Maybe (PoolId, VoteWeight)
forall a. [a] -> Int -> Maybe a
!? PerasSeatIndex -> Int
seatIndexToInt PerasSeatIndex
seatIndex
  pure $ MockPerasVotingCommitteeSchemeMember seatIndex voteWeight