{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Test.Cardano.Ledger.Shelley.Generator.ScriptClass (
ScriptClass (..),
Quantifier (..),
exponential,
anyOf,
allOf,
mOf,
keyPairs,
mkPayScriptHashMap,
mkStakeScriptHashMap,
mkScriptsFromKeyPair,
mkKeyPairs,
mkScripts,
mkScriptCombinations,
combinedScripts,
baseScripts,
scriptKeyCombinations,
scriptKeyCombination,
) where
import Cardano.Ledger.Core
import Cardano.Ledger.Keys (asWitness)
import Data.List (permutations)
import qualified Data.List as List
import qualified Data.Map.Strict as Map
import Data.Proxy
import Data.Tuple (swap)
import Data.Word (Word64)
import Test.Cardano.Ledger.Core.KeyPair (KeyPair (..), KeyPairs, vKey)
import Test.Cardano.Ledger.Shelley.Constants (Constants (..))
import Test.Cardano.Ledger.Shelley.Utils (RawSeed (..), mkKeyPair)
import Test.QuickCheck (Gen)
import qualified Test.QuickCheck as QC
class EraScript era => ScriptClass era where
basescript :: Proxy era -> KeyHash 'Witness -> Script era
isKey :: Proxy era -> Script era -> Maybe (KeyHash 'Witness)
isOnePhase :: Proxy era -> Script era -> Bool
isOnePhase Proxy era
_proxy Script era
_ = Bool
True
quantify :: Proxy era -> Script era -> Quantifier (Script era)
unQuantify :: Proxy era -> Quantifier (Script era) -> Script era
data Quantifier t = AllOf [t] | AnyOf [t] | MOf Int [t] | Leaf t
deriving ((forall a b. (a -> b) -> Quantifier a -> Quantifier b)
-> (forall a b. a -> Quantifier b -> Quantifier a)
-> Functor Quantifier
forall a b. a -> Quantifier b -> Quantifier a
forall a b. (a -> b) -> Quantifier a -> Quantifier b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Quantifier a -> Quantifier b
fmap :: forall a b. (a -> b) -> Quantifier a -> Quantifier b
$c<$ :: forall a b. a -> Quantifier b -> Quantifier a
<$ :: forall a b. a -> Quantifier b -> Quantifier a
Functor)
anyOf :: forall era. ScriptClass era => Proxy era -> [Script era] -> Script era
anyOf :: forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
anyOf Proxy era
prox [Script era]
xs = Proxy era -> Quantifier (Script era) -> Script era
forall era.
ScriptClass era =>
Proxy era -> Quantifier (Script era) -> Script era
unQuantify Proxy era
prox (Quantifier (Script era) -> Script era)
-> Quantifier (Script era) -> Script era
forall a b. (a -> b) -> a -> b
$ [Script era] -> Quantifier (Script era)
forall t. [t] -> Quantifier t
AnyOf [Script era]
xs
allOf :: forall era. ScriptClass era => Proxy era -> [Script era] -> Script era
allOf :: forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
allOf Proxy era
prox [Script era]
xs = Proxy era -> Quantifier (Script era) -> Script era
forall era.
ScriptClass era =>
Proxy era -> Quantifier (Script era) -> Script era
unQuantify Proxy era
prox (Quantifier (Script era) -> Script era)
-> Quantifier (Script era) -> Script era
forall a b. (a -> b) -> a -> b
$ [Script era] -> Quantifier (Script era)
forall t. [t] -> Quantifier t
AllOf [Script era]
xs
mOf :: forall era. ScriptClass era => Proxy era -> Int -> [Script era] -> Script era
mOf :: forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf Proxy era
prox Int
m [Script era]
xs = Proxy era -> Quantifier (Script era) -> Script era
forall era.
ScriptClass era =>
Proxy era -> Quantifier (Script era) -> Script era
unQuantify Proxy era
prox (Quantifier (Script era) -> Script era)
-> Quantifier (Script era) -> Script era
forall a b. (a -> b) -> a -> b
$ Int -> [Script era] -> Quantifier (Script era)
forall t. Int -> [t] -> Quantifier t
MOf Int
m [Script era]
xs
getFirst :: ([a] -> Bool) -> [[a]] -> [a]
getFirst :: forall a. ([a] -> Bool) -> [[a]] -> [a]
getFirst [a] -> Bool
_p [] = []
getFirst [a] -> Bool
p ([a]
xs : [[a]]
xss) = if [a] -> Bool
p [a]
xs then [a]
xs else ([a] -> Bool) -> [[a]] -> [a]
forall a. ([a] -> Bool) -> [[a]] -> [a]
getFirst [a] -> Bool
p [[a]]
xss
scriptKeyCombination ::
forall era.
ScriptClass era =>
Proxy era ->
Script era ->
[KeyHash 'Witness]
scriptKeyCombination :: forall era.
ScriptClass era =>
Proxy era -> Script era -> [KeyHash 'Witness]
scriptKeyCombination Proxy era
prox Script era
script = case Proxy era -> Script era -> Quantifier (Script era)
forall era.
ScriptClass era =>
Proxy era -> Script era -> Quantifier (Script era)
quantify Proxy era
prox Script era
script of
AllOf [Script era]
xs -> (Script era -> [KeyHash 'Witness])
-> [Script era] -> [KeyHash 'Witness]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Proxy era -> Script era -> [KeyHash 'Witness]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [KeyHash 'Witness]
scriptKeyCombination Proxy era
prox) [Script era]
xs
AnyOf [Script era]
xs -> ([KeyHash 'Witness] -> Bool)
-> [[KeyHash 'Witness]] -> [KeyHash 'Witness]
forall a. ([a] -> Bool) -> [[a]] -> [a]
getFirst (Bool -> Bool
not (Bool -> Bool)
-> ([KeyHash 'Witness] -> Bool) -> [KeyHash 'Witness] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [KeyHash 'Witness] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) ((Script era -> [KeyHash 'Witness])
-> [Script era] -> [[KeyHash 'Witness]]
forall a b. (a -> b) -> [a] -> [b]
map (Proxy era -> Script era -> [KeyHash 'Witness]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [KeyHash 'Witness]
scriptKeyCombination Proxy era
prox) [Script era]
xs)
MOf Int
m [Script era]
xs -> (Script era -> [KeyHash 'Witness])
-> [Script era] -> [KeyHash 'Witness]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Proxy era -> Script era -> [KeyHash 'Witness]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [KeyHash 'Witness]
scriptKeyCombination Proxy era
prox) (Int -> [Script era] -> [Script era]
forall a. Int -> [a] -> [a]
take Int
m [Script era]
xs)
Leaf Script era
t -> case Proxy era -> Script era -> Maybe (KeyHash 'Witness)
forall era.
ScriptClass era =>
Proxy era -> Script era -> Maybe (KeyHash 'Witness)
isKey Proxy era
prox Script era
t of
Just KeyHash 'Witness
hk -> [KeyHash 'Witness
hk]
Maybe (KeyHash 'Witness)
Nothing -> []
scriptKeyCombinations ::
forall era.
ScriptClass era =>
Proxy era ->
Script era ->
[[KeyHash 'Witness]]
scriptKeyCombinations :: forall era.
ScriptClass era =>
Proxy era -> Script era -> [[KeyHash 'Witness]]
scriptKeyCombinations Proxy era
prox Script era
script = case Proxy era -> Script era -> Quantifier (Script era)
forall era.
ScriptClass era =>
Proxy era -> Script era -> Quantifier (Script era)
quantify Proxy era
prox Script era
script of
AllOf [Script era]
xs -> [[[KeyHash 'Witness]] -> [KeyHash 'Witness]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[KeyHash 'Witness]] -> [KeyHash 'Witness])
-> [[KeyHash 'Witness]] -> [KeyHash 'Witness]
forall a b. (a -> b) -> a -> b
$ (Script era -> [[KeyHash 'Witness]])
-> [Script era] -> [[KeyHash 'Witness]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Proxy era -> Script era -> [[KeyHash 'Witness]]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [[KeyHash 'Witness]]
scriptKeyCombinations Proxy era
prox) [Script era]
xs]
AnyOf [Script era]
xs -> (Script era -> [[KeyHash 'Witness]])
-> [Script era] -> [[KeyHash 'Witness]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Proxy era -> Script era -> [[KeyHash 'Witness]]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [[KeyHash 'Witness]]
scriptKeyCombinations Proxy era
prox) [Script era]
xs
MOf Int
m [Script era]
xs ->
let perms :: [[Script era]]
perms = ([Script era] -> [Script era]) -> [[Script era]] -> [[Script era]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [Script era] -> [Script era]
forall a. Int -> [a] -> [a]
take Int
m) ([[Script era]] -> [[Script era]])
-> [[Script era]] -> [[Script era]]
forall a b. (a -> b) -> a -> b
$ [Script era] -> [[Script era]]
forall a. [a] -> [[a]]
permutations [Script era]
xs
in ([Script era] -> [KeyHash 'Witness])
-> [[Script era]] -> [[KeyHash 'Witness]]
forall a b. (a -> b) -> [a] -> [b]
map ([[KeyHash 'Witness]] -> [KeyHash 'Witness]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[KeyHash 'Witness]] -> [KeyHash 'Witness])
-> ([Script era] -> [[KeyHash 'Witness]])
-> [Script era]
-> [KeyHash 'Witness]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Script era -> [[KeyHash 'Witness]])
-> [Script era] -> [[KeyHash 'Witness]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Proxy era -> Script era -> [[KeyHash 'Witness]]
forall era.
ScriptClass era =>
Proxy era -> Script era -> [[KeyHash 'Witness]]
scriptKeyCombinations Proxy era
prox)) [[Script era]]
perms
Leaf Script era
t -> case Proxy era -> Script era -> Maybe (KeyHash 'Witness)
forall era.
ScriptClass era =>
Proxy era -> Script era -> Maybe (KeyHash 'Witness)
isKey Proxy era
prox Script era
t of
Just KeyHash 'Witness
hk -> [[KeyHash 'Witness
hk]]
Maybe (KeyHash 'Witness)
Nothing -> [[]]
mkScriptFromKey :: forall era. ScriptClass era => KeyPair 'Witness -> Script era
mkScriptFromKey :: forall era. ScriptClass era => KeyPair 'Witness -> Script era
mkScriptFromKey = Proxy era -> KeyHash 'Witness -> Script era
forall era.
ScriptClass era =>
Proxy era -> KeyHash 'Witness -> Script era
basescript (Proxy era
forall {k} (t :: k). Proxy t
Proxy :: Proxy era) (KeyHash 'Witness -> Script era)
-> (KeyPair 'Witness -> KeyHash 'Witness)
-> KeyPair 'Witness
-> Script era
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VKey 'Witness -> KeyHash 'Witness
forall (kd :: KeyRole). VKey kd -> KeyHash kd
hashKey (VKey 'Witness -> KeyHash 'Witness)
-> (KeyPair 'Witness -> VKey 'Witness)
-> KeyPair 'Witness
-> KeyHash 'Witness
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyPair 'Witness -> VKey 'Witness
forall (kd :: KeyRole). KeyPair kd -> VKey kd
vKey
mkScriptsFromKeyPair ::
forall era.
ScriptClass era =>
(KeyPair 'Payment, KeyPair 'Staking) ->
(Script era, Script era)
mkScriptsFromKeyPair :: forall era.
ScriptClass era =>
(KeyPair 'Payment, KeyPair 'Staking) -> (Script era, Script era)
mkScriptsFromKeyPair (KeyPair 'Payment
k0, KeyPair 'Staking
k1) =
(forall era. ScriptClass era => KeyPair 'Witness -> Script era
mkScriptFromKey @era (KeyPair 'Witness -> Script era) -> KeyPair 'Witness -> Script era
forall a b. (a -> b) -> a -> b
$ KeyPair 'Payment -> KeyPair 'Witness
forall (a :: KeyRole -> *) (r :: KeyRole).
HasKeyRole a =>
a r -> a 'Witness
asWitness KeyPair 'Payment
k0, forall era. ScriptClass era => KeyPair 'Witness -> Script era
mkScriptFromKey @era (KeyPair 'Witness -> Script era) -> KeyPair 'Witness -> Script era
forall a b. (a -> b) -> a -> b
$ KeyPair 'Staking -> KeyPair 'Witness
forall (a :: KeyRole -> *) (r :: KeyRole).
HasKeyRole a =>
a r -> a 'Witness
asWitness KeyPair 'Staking
k1)
mkScripts ::
forall era.
ScriptClass era =>
KeyPairs ->
[(Script era, Script era)]
mkScripts :: forall era.
ScriptClass era =>
KeyPairs -> [(Script era, Script era)]
mkScripts = ((KeyPair 'Payment, KeyPair 'Staking) -> (Script era, Script era))
-> KeyPairs -> [(Script era, Script era)]
forall a b. (a -> b) -> [a] -> [b]
map (forall era.
ScriptClass era =>
(KeyPair 'Payment, KeyPair 'Staking) -> (Script era, Script era)
mkScriptsFromKeyPair @era)
mkPayScriptHashMap ::
forall era.
ScriptClass era =>
[(Script era, Script era)] ->
Map.Map ScriptHash (Script era, Script era)
mkPayScriptHashMap :: forall era.
ScriptClass era =>
[(Script era, Script era)]
-> Map ScriptHash (Script era, Script era)
mkPayScriptHashMap [(Script era, Script era)]
scripts =
[(ScriptHash, (Script era, Script era))]
-> Map ScriptHash (Script era, Script era)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((Script era, Script era) -> (ScriptHash, (Script era, Script era))
f ((Script era, Script era)
-> (ScriptHash, (Script era, Script era)))
-> [(Script era, Script era)]
-> [(ScriptHash, (Script era, Script era))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Script era, Script era)]
scripts)
where
f :: (Script era, Script era) -> (ScriptHash, (Script era, Script era))
f script :: (Script era, Script era)
script@(Script era
pay, Script era
_ssStake) = (forall era. EraScript era => Script era -> ScriptHash
hashScript @era Script era
pay, (Script era, Script era)
script)
mkStakeScriptHashMap ::
forall era.
ScriptClass era =>
[(Script era, Script era)] ->
Map.Map ScriptHash (Script era, Script era)
mkStakeScriptHashMap :: forall era.
ScriptClass era =>
[(Script era, Script era)]
-> Map ScriptHash (Script era, Script era)
mkStakeScriptHashMap [(Script era, Script era)]
scripts =
[(ScriptHash, (Script era, Script era))]
-> Map ScriptHash (Script era, Script era)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((Script era, Script era) -> (ScriptHash, (Script era, Script era))
f ((Script era, Script era)
-> (ScriptHash, (Script era, Script era)))
-> [(Script era, Script era)]
-> [(ScriptHash, (Script era, Script era))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Script era, Script era)]
scripts)
where
f :: (Script era, Script era) -> (ScriptHash, (Script era, Script era))
f script :: (Script era, Script era)
script@(Script era
_pay, Script era
stake) = (forall era. EraScript era => Script era -> ScriptHash
hashScript @era Script era
stake, (Script era, Script era)
script)
mkScriptCombinations ::
forall era.
ScriptClass era =>
[(Script era, Script era)] ->
[(Script era, Script era)]
mkScriptCombinations :: forall era.
ScriptClass era =>
[(Script era, Script era)] -> [(Script era, Script era)]
mkScriptCombinations [(Script era, Script era)]
msigs =
if [(Script era, Script era)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Script era, Script era)]
msigs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
3
then [Char] -> [(Script era, Script era)]
forall a. HasCallStack => [Char] -> a
error [Char]
"length of input msigs must be at least 3"
else
( ([(Script era, Script era)]
-> [(Script era, Script era)] -> [(Script era, Script era)])
-> [(Script era, Script era)]
-> [[(Script era, Script era)]]
-> [(Script era, Script era)]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' [(Script era, Script era)]
-> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. [a] -> [a] -> [a]
(++) [] ([[(Script era, Script era)]] -> [(Script era, Script era)])
-> [[(Script era, Script era)]] -> [(Script era, Script era)]
forall a b. (a -> b) -> a -> b
$
do
(Script era
k1, Script era
k2) <- [(Script era, Script era)]
msigs
(Script era
k3, Script era
k4) <- [(Script era, Script era)]
msigs [(Script era, Script era)]
-> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Eq a => [a] -> [a] -> [a]
List.\\ [(Script era
k1, Script era
k2)]
(Script era
k5, Script era
k6) <- [(Script era, Script era)]
msigs [(Script era, Script era)]
-> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Eq a => [a] -> [a] -> [a]
List.\\ [(Script era
k1, Script era
k2), (Script era
k3, Script era
k4)]
[(Script era, Script era)] -> [[(Script era, Script era)]]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
[ (Script era
pay, Script era
stake)
| Script era
pay <-
[ Proxy era -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
anyOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) [Script era
k1, Script era
k3, Script era
k5]
, Proxy era -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
allOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) [Script era
k1, Script era
k3, Script era
k5]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
1 [Script era
k1, Script era
k3, Script era
k5]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
2 [Script era
k1, Script era
k3, Script era
k5]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
3 [Script era
k1, Script era
k3, Script era
k5]
]
, Script era
stake <-
[ Proxy era -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
anyOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) [Script era
k2, Script era
k4, Script era
k6]
, Proxy era -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> [Script era] -> Script era
allOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) [Script era
k2, Script era
k4, Script era
k6]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
1 [Script era
k2, Script era
k4, Script era
k6]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
2 [Script era
k2, Script era
k4, Script era
k6]
, Proxy era -> Int -> [Script era] -> Script era
forall era.
ScriptClass era =>
Proxy era -> Int -> [Script era] -> Script era
mOf (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Int
3 [Script era
k2, Script era
k4, Script era
k6]
]
]
) ::
[(Script era, Script era)]
baseScripts ::
forall era.
ScriptClass era =>
Constants ->
[(Script era, Script era)]
baseScripts :: forall era.
ScriptClass era =>
Constants -> [(Script era, Script era)]
baseScripts Constants
c = forall era.
ScriptClass era =>
KeyPairs -> [(Script era, Script era)]
mkScripts @era (Constants -> KeyPairs
keyPairs Constants
c)
combinedScripts ::
forall era.
ScriptClass era =>
Constants ->
[(Script era, Script era)]
combinedScripts :: forall era.
ScriptClass era =>
Constants -> [(Script era, Script era)]
combinedScripts c :: Constants
c@(Constants {Int
numBaseScripts :: Int
numBaseScripts :: Constants -> Int
numBaseScripts}) =
forall era.
ScriptClass era =>
[(Script era, Script era)] -> [(Script era, Script era)]
mkScriptCombinations @era ([(Script era, Script era)] -> [(Script era, Script era)])
-> ([(Script era, Script era)] -> [(Script era, Script era)])
-> [(Script era, Script era)]
-> [(Script era, Script era)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Int -> [a] -> [a]
take Int
numBaseScripts ([(Script era, Script era)] -> [(Script era, Script era)])
-> [(Script era, Script era)] -> [(Script era, Script era)]
forall a b. (a -> b) -> a -> b
$ forall era.
ScriptClass era =>
Constants -> [(Script era, Script era)]
baseScripts @era Constants
c
keyPairs :: Constants -> KeyPairs
keyPairs :: Constants -> KeyPairs
keyPairs Constants {Word64
numKeyPairs :: Word64
numKeyPairs :: Constants -> Word64
numKeyPairs} = Word64 -> (KeyPair 'Payment, KeyPair 'Staking)
forall (kr :: KeyRole) (kr' :: KeyRole).
Word64 -> (KeyPair kr, KeyPair kr')
mkKeyPairs (Word64 -> (KeyPair 'Payment, KeyPair 'Staking))
-> [Word64] -> KeyPairs
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Word64
1 .. Word64
numKeyPairs]
mkKeyPairs ::
Word64 ->
(KeyPair kr, KeyPair kr')
mkKeyPairs :: forall (kr :: KeyRole) (kr' :: KeyRole).
Word64 -> (KeyPair kr, KeyPair kr')
mkKeyPairs Word64
n =
(Word64 -> KeyPair kr
forall {kd :: KeyRole}. Word64 -> KeyPair kd
mkKeyPair_ (Word64
2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
n), Word64 -> KeyPair kr'
forall {kd :: KeyRole}. Word64 -> KeyPair kd
mkKeyPair_ (Word64
2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1))
where
mkKeyPair_ :: Word64 -> KeyPair kd
mkKeyPair_ Word64
n_ =
((VKey kd -> SignKeyDSIGN DSIGN -> KeyPair kd)
-> (VKey kd, SignKeyDSIGN DSIGN) -> KeyPair kd
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry VKey kd -> SignKeyDSIGN DSIGN -> KeyPair kd
forall (kd :: KeyRole). VKey kd -> SignKeyDSIGN DSIGN -> KeyPair kd
KeyPair ((VKey kd, SignKeyDSIGN DSIGN) -> KeyPair kd)
-> ((SignKeyDSIGN DSIGN, VKey kd) -> (VKey kd, SignKeyDSIGN DSIGN))
-> (SignKeyDSIGN DSIGN, VKey kd)
-> KeyPair kd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SignKeyDSIGN DSIGN, VKey kd) -> (VKey kd, SignKeyDSIGN DSIGN)
forall a b. (a, b) -> (b, a)
swap)
(RawSeed -> (SignKeyDSIGN DSIGN, VKey kd)
forall (kd :: KeyRole). RawSeed -> (SignKeyDSIGN DSIGN, VKey kd)
mkKeyPair (Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> RawSeed
RawSeed Word64
n_ Word64
n_ Word64
n_ Word64
n_ Word64
n_))
exponential :: Integer -> Integer -> Gen Integer
exponential :: Integer -> Integer -> Gen Integer
exponential Integer
minc Integer
maxc = [(Int, Gen Integer)] -> Gen Integer
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
QC.frequency [(Int, Gen Integer)]
spread
where
width :: Integer
width = (Integer
maxc Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
minc) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
n
deltas :: [Gen Integer]
deltas = [(Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
QC.choose (Integer
minc Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
width, Integer
minc Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
width) | Integer
i <- [Integer
1 .. Integer
n]]
scales :: [Int]
scales = [Int
1, Int
2, Int
4, Int
6, Int
4, Int
2, Int
1]
n :: Integer
n = Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
scales)
spread :: [(Int, Gen Integer)]
spread = [Int] -> [Gen Integer] -> [(Int, Gen Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
scales [Gen Integer]
deltas