{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Test.Cardano.Ledger.Constrained.Scripts (
allPlutusScripts,
genCoreScript,
spendPlutusScripts,
sufficientScript,
) where
import Cardano.Ledger.Alonzo.Scripts (AlonzoScript (..))
import Cardano.Ledger.Alonzo.Tx (IsValid (..))
import Cardano.Ledger.Core (NativeScript, Script, getNativeScript, hashScript)
import Cardano.Ledger.Hashes (ScriptHash)
import Cardano.Ledger.Keys (
KeyHash (..),
KeyRole (..),
)
import Cardano.Slotting.Slot (SlotNo (..))
import Control.Monad (replicateM)
import Data.Foldable (toList)
import qualified Data.List as List
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe.Strict (StrictMaybe (..))
import qualified Data.Sequence.Strict as Seq
import Data.Set (Set)
import qualified Data.Set as Set
import Numeric.Natural
import Test.Cardano.Ledger.Constrained.Combinators (genFromMap)
import Test.Cardano.Ledger.Core.KeyPair (KeyPair (..))
import Test.Cardano.Ledger.Generic.Functions (
alwaysFalse,
alwaysTrue,
primaryLanguage,
)
import Test.Cardano.Ledger.Generic.GenState
import Test.Cardano.Ledger.Generic.Proof
import Test.QuickCheck
import Cardano.Ledger.Allegra.Scripts (
AllegraEraScript,
Timelock,
ValidityInterval (..),
pattern RequireTimeExpire,
pattern RequireTimeStart,
)
import Cardano.Ledger.Shelley.Scripts (
MultiSig,
ShelleyEraScript,
pattern RequireAllOf,
pattern RequireAnyOf,
pattern RequireMOf,
pattern RequireSignature,
)
type KeyMap era = Map (KeyHash 'Witness) (KeyPair 'Witness)
genMultiSig ::
forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
KeyMap era ->
Proof era ->
Gen (MultiSig era)
genMultiSig :: forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
KeyMap era -> Proof era -> Gen (MultiSig era)
genMultiSig KeyMap era
keymap Proof era
_proof = do
let genNestedMultiSig :: Natural -> Gen (MultiSig era)
genNestedMultiSig :: Natural -> Gen (MultiSig era)
genNestedMultiSig Natural
k
| Natural
k forall a. Ord a => a -> a -> Bool
> Natural
0 =
forall a. HasCallStack => [Gen a] -> Gen a
oneof forall a b. (a -> b) -> a -> b
$
[Gen (MultiSig era)]
nonRecTimelocks forall a. [a] -> [a] -> [a]
++ [Natural -> Gen (MultiSig era)
requireAllOf Natural
k, Natural -> Gen (MultiSig era)
requireAnyOf Natural
k, Natural -> Gen (MultiSig era)
requireMOf Natural
k]
| Bool
otherwise = forall a. HasCallStack => [Gen a] -> Gen a
oneof [Gen (MultiSig era)]
nonRecTimelocks
nonRecTimelocks :: [Gen (MultiSig era)]
nonRecTimelocks = [Gen (MultiSig era)
requireSignature]
requireSignature :: Gen (MultiSig era)
requireSignature =
forall era.
ShelleyEraScript era =>
KeyHash 'Witness -> NativeScript era
RequireSignature @era forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k a. [String] -> Map k a -> Gen (k, a)
genFromMap [String
"from requiresSignature in genMultiSig"] KeyMap era
keymap
requireAllOf :: Natural -> Gen (MultiSig era)
requireAllOf Natural
k = do
Int
n <- Gen Int
nonNegativeSingleDigitInt
forall era.
ShelleyEraScript era =>
StrictSeq (NativeScript era) -> NativeScript era
RequireAllOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (MultiSig era)
genNestedMultiSig (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
requireAnyOf :: Natural -> Gen (MultiSig era)
requireAnyOf Natural
k = do
Int
n <- Gen Int
positiveSingleDigitInt
forall era.
ShelleyEraScript era =>
StrictSeq (NativeScript era) -> NativeScript era
RequireAnyOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (MultiSig era)
genNestedMultiSig (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
requireMOf :: Natural -> Gen (MultiSig era)
requireMOf Natural
k = do
Int
n <- Gen Int
nonNegativeSingleDigitInt
Int
m <- forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
n)
forall era.
ShelleyEraScript era =>
Int -> StrictSeq (NativeScript era) -> NativeScript era
RequireMOf Int
m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (MultiSig era)
genNestedMultiSig (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
Natural -> Gen (MultiSig era)
genNestedMultiSig (Natural
2 :: Natural)
genTimelock ::
forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era ->
ValidityInterval ->
Proof era ->
Gen (Timelock era)
genTimelock :: forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap (ValidityInterval StrictMaybe SlotNo
mBefore StrictMaybe SlotNo
mAfter) Proof era
_proof = do
let genNestedTimelock :: Natural -> Gen (Timelock era)
genNestedTimelock Natural
k
| Natural
k forall a. Ord a => a -> a -> Bool
> Natural
0 =
forall a. HasCallStack => [Gen a] -> Gen a
oneof forall a b. (a -> b) -> a -> b
$
[Gen (Timelock era)]
nonRecTimelocks forall a. [a] -> [a] -> [a]
++ [Natural -> Gen (Timelock era)
requireAllOf Natural
k, Natural -> Gen (Timelock era)
requireAnyOf Natural
k, Natural -> Gen (Timelock era)
requireMOf Natural
k]
| Bool
otherwise = forall a. HasCallStack => [Gen a] -> Gen a
oneof [Gen (Timelock era)]
nonRecTimelocks
nonRecTimelocks :: [Gen (Timelock era)]
nonRecTimelocks :: [Gen (Timelock era)]
nonRecTimelocks =
[ Gen (Timelock era)
r
| SJust Gen (Timelock era)
r <-
[ forall {era}.
AllegraEraScript era =>
SlotNo -> Gen (NativeScript era)
requireTimeStart forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictMaybe SlotNo
mBefore
, forall {era}.
AllegraEraScript era =>
SlotNo -> Gen (NativeScript era)
requireTimeExpire forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictMaybe SlotNo
mAfter
, forall a. a -> StrictMaybe a
SJust Gen (Timelock era)
requireSignature
]
]
requireSignature :: Gen (Timelock era)
requireSignature = forall era.
ShelleyEraScript era =>
KeyHash 'Witness -> NativeScript era
RequireSignature forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k a. [String] -> Map k a -> Gen (k, a)
genFromMap [String
"from requiresSignature in genTimelock"] KeyMap era
keymap
requireAllOf :: Natural -> Gen (Timelock era)
requireAllOf Natural
k = do
Int
n <- Gen Int
nonNegativeSingleDigitInt
forall era.
ShelleyEraScript era =>
StrictSeq (NativeScript era) -> NativeScript era
RequireAllOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (Timelock era)
genNestedTimelock (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
requireAnyOf :: Natural -> Gen (Timelock era)
requireAnyOf Natural
k = do
Int
n <- Gen Int
positiveSingleDigitInt
forall era.
ShelleyEraScript era =>
StrictSeq (NativeScript era) -> NativeScript era
RequireAnyOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (Timelock era)
genNestedTimelock (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
requireMOf :: Natural -> Gen (Timelock era)
requireMOf Natural
k = do
Int
n <- Gen Int
nonNegativeSingleDigitInt
Int
m <- forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
n)
forall era.
ShelleyEraScript era =>
Int -> StrictSeq (NativeScript era) -> NativeScript era
RequireMOf Int
m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> StrictSeq a
Seq.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Natural -> Gen (Timelock era)
genNestedTimelock (Natural
k forall a. Num a => a -> a -> a
- Natural
1))
requireTimeStart :: SlotNo -> Gen (NativeScript era)
requireTimeStart (SlotNo Word64
validFrom) = do
Word64
minSlotNo <- forall a. Random a => (a, a) -> Gen a
choose (forall a. Bounded a => a
minBound, Word64
validFrom)
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall era. AllegraEraScript era => SlotNo -> NativeScript era
RequireTimeStart (Word64 -> SlotNo
SlotNo Word64
minSlotNo)
requireTimeExpire :: SlotNo -> Gen (NativeScript era)
requireTimeExpire (SlotNo Word64
validTill) = do
Word64
maxSlotNo <- forall a. Random a => (a, a) -> Gen a
choose (Word64
validTill, forall a. Bounded a => a
maxBound)
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall era. AllegraEraScript era => SlotNo -> NativeScript era
RequireTimeExpire (Word64 -> SlotNo
SlotNo Word64
maxSlotNo)
Natural -> Gen (Timelock era)
genNestedTimelock (Natural
2 :: Natural)
genPlutusScript ::
forall era.
PlutusPurposeTag ->
Proof era ->
Gen (Bool, Script era)
genPlutusScript :: forall era. PlutusPurposeTag -> Proof era -> Gen (Bool, Script era)
genPlutusScript PlutusPurposeTag
tag Proof era
proof = do
Bool
isValid <- forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency [(Int
5, forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False), (Int
95, forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)]
let numArgs :: Natural
numArgs = case (Proof era
proof, PlutusPurposeTag
tag) of
(Proof era
Conway, PlutusPurposeTag
Spending) -> Natural
2
(Proof era
Conway, PlutusPurposeTag
_) -> Natural
1
(Proof era
Babbage, PlutusPurposeTag
Spending) -> Natural
2
(Proof era
Babbage, PlutusPurposeTag
_) -> Natural
1
(Proof era
_, PlutusPurposeTag
Spending) -> Natural
3
(Proof era
_, PlutusPurposeTag
_) -> Natural
2
let mlanguage :: Maybe Language
mlanguage = forall era. Proof era -> Maybe Language
primaryLanguage Proof era
proof
if Bool
isValid
then (,) Bool
isValid forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era. Proof era -> Maybe Language -> Natural -> Script era
alwaysTrue Proof era
proof Maybe Language
mlanguage forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+ Natural
numArgs) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. HasCallStack => [a] -> Gen a
elements [Natural
0, Natural
1, Natural
2, Natural
3 :: Natural])
else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (Bool
isValid, forall era. Proof era -> Maybe Language -> Natural -> Script era
alwaysFalse Proof era
proof Maybe Language
mlanguage Natural
numArgs)
genCoreScript ::
forall era.
Proof era ->
PlutusPurposeTag ->
KeyMap era ->
ValidityInterval ->
Gen (Script era)
genCoreScript :: forall era.
Proof era
-> PlutusPurposeTag
-> KeyMap era
-> ValidityInterval
-> Gen (Script era)
genCoreScript Proof era
proof PlutusPurposeTag
tag KeyMap era
keymap ValidityInterval
vi = case Proof era
proof of
Proof era
Conway ->
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
1, forall era. Timelock era -> AlonzoScript era
TimelockScript forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap ValidityInterval
vi Proof era
proof)
]
Proof era
Babbage ->
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
1, forall era. Timelock era -> AlonzoScript era
TimelockScript forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap ValidityInterval
vi Proof era
proof)
, (Int
1, forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era. PlutusPurposeTag -> Proof era -> Gen (Bool, Script era)
genPlutusScript PlutusPurposeTag
tag Proof era
proof)
]
Proof era
Alonzo ->
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
1, forall era. Timelock era -> AlonzoScript era
TimelockScript forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap ValidityInterval
vi Proof era
proof)
, (Int
1, forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era. PlutusPurposeTag -> Proof era -> Gen (Bool, Script era)
genPlutusScript PlutusPurposeTag
tag Proof era
proof)
]
Proof era
Mary -> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap ValidityInterval
vi Proof era
proof
Proof era
Allegra -> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
KeyMap era -> ValidityInterval -> Proof era -> Gen (Timelock era)
genTimelock KeyMap era
keymap ValidityInterval
vi Proof era
proof
Proof era
Shelley -> forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
KeyMap era -> Proof era -> Gen (MultiSig era)
genMultiSig KeyMap era
keymap Proof era
proof
allPlutusScripts ::
Reflect era => Proof era -> Map ScriptHash (IsValid, Script era)
allPlutusScripts :: forall era.
Reflect era =>
Proof era -> Map ScriptHash (IsValid, Script era)
allPlutusScripts Proof era
proof =
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map forall {era} {a}.
EraScript era =>
(a, Script era) -> (ScriptHash, (a, Script era))
hash (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall era.
Proof era -> PlutusPurposeTag -> [(IsValid, Script era)]
plutusByTag Proof era
proof) (forall era. Proof era -> [PlutusPurposeTag]
plutusPurposeTags Proof era
proof))
where
hash :: (a, Script era) -> (ScriptHash, (a, Script era))
hash (a
b, Script era
s) = (forall era. EraScript era => Script era -> ScriptHash
hashScript Script era
s, (a
b, Script era
s))
spendPlutusScripts ::
Reflect era => Proof era -> Map ScriptHash (IsValid, Script era)
spendPlutusScripts :: forall era.
Reflect era =>
Proof era -> Map ScriptHash (IsValid, Script era)
spendPlutusScripts Proof era
proof = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (forall a b. (a -> b) -> [a] -> [b]
map forall {era} {a}.
EraScript era =>
(a, Script era) -> (ScriptHash, (a, Script era))
hash (forall era.
Proof era -> PlutusPurposeTag -> [(IsValid, Script era)]
plutusByTag Proof era
proof PlutusPurposeTag
Spending))
where
hash :: (a, Script era) -> (ScriptHash, (a, Script era))
hash (a
b, Script era
s) = (forall era. EraScript era => Script era -> ScriptHash
hashScript Script era
s, (a
b, Script era
s))
plutusByTag :: Proof era -> PlutusPurposeTag -> [(IsValid, Script era)]
plutusByTag :: forall era.
Proof era -> PlutusPurposeTag -> [(IsValid, Script era)]
plutusByTag Proof era
proof PlutusPurposeTag
tag = [(IsValid, Script era)]
trueS forall a. [a] -> [a] -> [a]
++ [(IsValid, Script era)]
falseS
where
numArgs :: Natural
numArgs = case (Proof era
proof, PlutusPurposeTag
tag) of
(Proof era
Conway, PlutusPurposeTag
Spending) -> Natural
2
(Proof era
Conway, PlutusPurposeTag
_) -> Natural
1
(Proof era
Babbage, PlutusPurposeTag
Spending) -> Natural
2
(Proof era
Babbage, PlutusPurposeTag
_) -> Natural
1
(Proof era
_, PlutusPurposeTag
Spending) -> Natural
3
(Proof era
_, PlutusPurposeTag
_) -> Natural
2
trueS :: [(IsValid, Script era)]
trueS = [(Bool -> IsValid
IsValid Bool
True, forall era. Proof era -> Maybe Language -> Natural -> Script era
alwaysTrue Proof era
proof Maybe Language
mlanguage (Natural
numArgs forall a. Num a => a -> a -> a
+ Natural
n)) | Natural
n <- [Natural
0, Natural
1, Natural
2, Natural
3 :: Natural]]
falseS :: [(IsValid, Script era)]
falseS = [(Bool -> IsValid
IsValid Bool
False, forall era. Proof era -> Maybe Language -> Natural -> Script era
alwaysFalse Proof era
proof Maybe Language
mlanguage Natural
numArgs)]
mlanguage :: Maybe Language
mlanguage = forall era. Proof era -> Maybe Language
primaryLanguage Proof era
proof
sufficientMultiSig ::
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era ->
Set (KeyHash 'Witness)
sufficientMultiSig :: forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era -> Set (KeyHash 'Witness)
sufficientMultiSig MultiSig era
x = case MultiSig era
x of
RequireSignature KeyHash 'Witness
kh -> forall a. a -> Set a
Set.singleton KeyHash 'Witness
kh
RequireAllOf StrictSeq (NativeScript era)
xs -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions (forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era -> Set (KeyHash 'Witness)
sufficientMultiSig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictSeq (NativeScript era)
xs)
RequireAnyOf StrictSeq (NativeScript era)
xs ->
case forall a. (a -> a -> Ordering) -> [a] -> [a]
List.sortBy forall {a} {a}. Set a -> Set a -> Ordering
p (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> Bool
Set.null) (forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era -> Set (KeyHash 'Witness)
sufficientMultiSig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList StrictSeq (NativeScript era)
xs))) of
[] -> forall a. Set a
Set.empty
(Set (KeyHash 'Witness)
s : [Set (KeyHash 'Witness)]
_) -> Set (KeyHash 'Witness)
s
RequireMOf Int
n StrictSeq (NativeScript era)
xs -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions (forall a. Int -> [a] -> [a]
take Int
n (forall a. (a -> a -> Ordering) -> [a] -> [a]
List.sortBy forall {a} {a}. Set a -> Set a -> Ordering
p (forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era -> Set (KeyHash 'Witness)
sufficientMultiSig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList StrictSeq (NativeScript era)
xs))))
MultiSig era
_ -> forall a. HasCallStack => String -> a
error String
"Impossible: All NativeScripts should have been accounted for"
where
p :: Set a -> Set a -> Ordering
p Set a
a Set a
b = forall a. Ord a => a -> a -> Ordering
compare (forall a. Set a -> Int
Set.size Set a
a) (forall a. Set a -> Int
Set.size Set a
b)
sufficientTimelock ::
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era ->
Set (KeyHash 'Witness)
sufficientTimelock :: forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock Timelock era
x = case Timelock era
x of
RequireSignature KeyHash 'Witness
kh -> forall a. a -> Set a
Set.singleton KeyHash 'Witness
kh
RequireAllOf StrictSeq (NativeScript era)
xs -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock StrictSeq (NativeScript era)
xs)
RequireAnyOf StrictSeq (NativeScript era)
xs ->
case forall a. (a -> a -> Ordering) -> [a] -> [a]
List.sortBy forall {a} {a}. Set a -> Set a -> Ordering
p (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> Bool
Set.null) (forall a b. (a -> b) -> [a] -> [b]
map forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList StrictSeq (NativeScript era)
xs))) of
[] -> forall a. Set a
Set.empty
(Set (KeyHash 'Witness)
s : [Set (KeyHash 'Witness)]
_) -> Set (KeyHash 'Witness)
s
RequireMOf Int
n StrictSeq (NativeScript era)
xs -> forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions (forall a. Int -> [a] -> [a]
take Int
n (forall a. (a -> a -> Ordering) -> [a] -> [a]
List.sortBy forall {a} {a}. Set a -> Set a -> Ordering
p (forall a b. (a -> b) -> [a] -> [b]
map forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList StrictSeq (NativeScript era)
xs))))
RequireTimeExpire {} -> forall a. Set a
Set.empty
RequireTimeStart {} -> forall a. Set a
Set.empty
where
p :: Set a -> Set a -> Ordering
p Set a
a Set a
b = forall a. Ord a => a -> a -> Ordering
compare (forall a. Set a -> Int
Set.size Set a
a) (forall a. Set a -> Int
Set.size Set a
b)
sufficientScript :: Proof era -> Script era -> Set (KeyHash 'Witness)
sufficientScript :: forall era. Proof era -> Script era -> Set (KeyHash 'Witness)
sufficientScript Proof era
p Script era
s = case Proof era
p of
Proof era
Shelley -> forall era.
(ShelleyEraScript era, NativeScript era ~ MultiSig era) =>
MultiSig era -> Set (KeyHash 'Witness)
sufficientMultiSig Script era
s
Proof era
Allegra -> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock Script era
s
Proof era
Mary -> forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock Script era
s
Proof era
Alonzo -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Set a
Set.empty forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock (forall era. EraScript era => Script era -> Maybe (NativeScript era)
getNativeScript Script era
s)
Proof era
Babbage -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Set a
Set.empty forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock (forall era. EraScript era => Script era -> Maybe (NativeScript era)
getNativeScript Script era
s)
Proof era
Conway -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Set a
Set.empty forall era.
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
Timelock era -> Set (KeyHash 'Witness)
sufficientTimelock (forall era. EraScript era => Script era -> Maybe (NativeScript era)
getNativeScript Script era
s)