{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Test.Cardano.Ledger.Shelley.Generator.EraGen (
genUtxo0,
genesisId,
EraGen (..),
MinLEDGER_STS,
MinCHAIN_STS,
MinUTXO_STS,
MinGenTxout (..),
Label (..),
Sets (..),
someKeyPairs,
allScripts,
mkDummyHash,
) where
import Cardano.Ledger.Address (Addr)
import Cardano.Ledger.BaseTypes (ShelleyBase, StrictMaybe)
import Cardano.Ledger.Block (Block (..))
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Core
import Cardano.Ledger.Hashes (unsafeMakeSafeHash)
import Cardano.Ledger.Keys (WitVKey)
import Cardano.Ledger.Shelley.API (
LedgerEnv,
LedgerState,
ShelleyLedgersEnv,
)
import Cardano.Ledger.Shelley.LedgerState (StashedAVVMAddresses, UTxOState (..))
import Cardano.Ledger.Shelley.PParams (Update)
import Cardano.Ledger.Shelley.Rules (UtxoEnv)
import Cardano.Ledger.Shelley.TxBody (ShelleyEraTxBody, Withdrawals)
import Cardano.Ledger.State (EraCertState, UTxO)
import Cardano.Ledger.TxIn (TxId (TxId), TxIn)
import Cardano.Protocol.TPraos.BHeader (BHeader)
import Cardano.Slotting.Slot (SlotNo)
import Control.State.Transition.Extended (STS (..))
import Data.Bifunctor (bimap)
import Data.Default (Default)
import Data.Map (Map)
import Data.Sequence (Seq)
import Data.Sequence.Strict (StrictSeq)
import Data.Set (Set)
import Lens.Micro
import Test.Cardano.Ledger.Binary.Random (mkDummyHash)
import Test.Cardano.Ledger.Core.KeyPair (KeyPairs, mkAddr)
import Test.Cardano.Ledger.Shelley.ConcreteCryptoTypes (MockCrypto)
import Test.Cardano.Ledger.Shelley.Constants (Constants (..))
import Test.Cardano.Ledger.Shelley.Generator.Core (
GenEnv (..),
ScriptInfo,
TwoPhase2ArgInfo (..),
TwoPhase3ArgInfo (..),
genesisCoins,
)
import Test.Cardano.Ledger.Shelley.Generator.ScriptClass (
ScriptClass,
baseScripts,
combinedScripts,
keyPairs,
)
import Test.Cardano.Ledger.Shelley.Rules.Chain (CHAIN, ChainState)
import Test.Cardano.Ledger.Shelley.Utils (Split)
import Test.QuickCheck (Gen, choose, shuffle)
type MinLEDGER_STS era =
( Environment (EraRule "LEDGERS" era) ~ ShelleyLedgersEnv era
, BaseM (EraRule "LEDGER" era) ~ ShelleyBase
, Signal (EraRule "LEDGER" era) ~ Tx era
, State (EraRule "LEDGER" era) ~ LedgerState era
, Environment (EraRule "LEDGER" era) ~ LedgerEnv era
, BaseM (EraRule "LEDGERS" era) ~ ShelleyBase
, State (EraRule "LEDGERS" era) ~ LedgerState era
, Signal (EraRule "LEDGERS" era) ~ Seq (Tx era)
, STS (EraRule "LEDGER" era)
)
type MinCHAIN_STS era =
( STS (CHAIN era)
, BaseM (CHAIN era) ~ ShelleyBase
, Environment (CHAIN era) ~ ()
, State (CHAIN era) ~ ChainState era
, Signal (CHAIN era) ~ Block (BHeader MockCrypto) era
)
type MinUTXO_STS era =
( STS (EraRule "UTXOW" era)
, BaseM (EraRule "UTXOW" era) ~ ShelleyBase
, State (EraRule "UTXOW" era) ~ UTxOState era
, Environment (EraRule "UTXOW" era) ~ UtxoEnv era
, Signal (EraRule "UTXOW" era) ~ Tx era
, State (EraRule "UTXO" era) ~ UTxOState era
, Environment (EraRule "UTXO" era) ~ UtxoEnv era
, Signal (EraRule "UTXO" era) ~ Tx era
)
class Show (TxOut era) => MinGenTxout era where
calcEraMinUTxO :: TxOut era -> PParams era -> Coin
addValToTxOut :: Value era -> TxOut era -> TxOut era
genEraTxOut :: GenEnv c era -> Gen (Value era) -> [Addr] -> Gen [TxOut era]
class
( EraSegWits era
, ShelleyEraTxBody era
, Split (Value era)
, ScriptClass era
, EraPParams era
, MinGenTxout era
, Default (StashedAVVMAddresses era)
, EraCertState era
) =>
EraGen era
where
genGenesisValue :: GenEnv c era -> Gen (Value era)
genEraTwoPhase3Arg :: [TwoPhase3ArgInfo era]
genEraTwoPhase3Arg = []
genEraTwoPhase2Arg :: [TwoPhase2ArgInfo era]
genEraTwoPhase2Arg = []
genEraTxBody ::
GenEnv c era ->
UTxO era ->
PParams era ->
SlotNo ->
Set TxIn ->
StrictSeq (TxOut era) ->
StrictSeq (TxCert era) ->
Withdrawals ->
Coin ->
StrictMaybe (Update era) ->
StrictMaybe TxAuxDataHash ->
Gen (TxBody era, [Script era])
genEraAuxiliaryData :: Constants -> Gen (StrictMaybe (TxAuxData era))
updateEraTxBody ::
UTxO era ->
PParams era ->
TxWits era ->
TxBody era ->
Coin ->
Set TxIn ->
TxOut era ->
TxBody era
addInputs :: TxBody era -> Set TxIn -> TxBody era
addInputs TxBody era
txb Set TxIn
_ins = TxBody era
txb
genEraPParamsUpdate :: Constants -> PParams era -> Gen (PParamsUpdate era)
genEraPParams :: Constants -> Gen (PParams era)
genEraTxWits ::
(UTxO era, TxBody era, ScriptInfo era) ->
Set (WitVKey 'Witness) ->
Map ScriptHash (Script era) ->
TxWits era
genEraGoodTxOut :: TxOut era -> Bool
genEraGoodTxOut TxOut era
_ = Bool
True
constructTx ::
TxBody era ->
TxWits era ->
StrictMaybe (TxAuxData era) ->
Tx era
constructTx TxBody era
txBody TxWits era
txWits StrictMaybe (TxAuxData era)
txAuxData =
TxBody era -> Tx era
forall era. EraTx era => TxBody era -> Tx era
mkBasicTx TxBody era
txBody Tx era -> (Tx era -> Tx era) -> Tx era
forall a b. a -> (a -> b) -> b
& (TxWits era -> Identity (TxWits era))
-> Tx era -> Identity (Tx era)
forall era. EraTx era => Lens' (Tx era) (TxWits era)
Lens' (Tx era) (TxWits era)
witsTxL ((TxWits era -> Identity (TxWits era))
-> Tx era -> Identity (Tx era))
-> TxWits era -> Tx era -> Tx era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ TxWits era
txWits Tx era -> (Tx era -> Tx era) -> Tx era
forall a b. a -> (a -> b) -> b
& (StrictMaybe (TxAuxData era)
-> Identity (StrictMaybe (TxAuxData era)))
-> Tx era -> Identity (Tx era)
forall era.
EraTx era =>
Lens' (Tx era) (StrictMaybe (TxAuxData era))
Lens' (Tx era) (StrictMaybe (TxAuxData era))
auxDataTxL ((StrictMaybe (TxAuxData era)
-> Identity (StrictMaybe (TxAuxData era)))
-> Tx era -> Identity (Tx era))
-> StrictMaybe (TxAuxData era) -> Tx era -> Tx era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ StrictMaybe (TxAuxData era)
txAuxData
genEraScriptCost :: PParams era -> Script era -> Coin
genEraScriptCost PParams era
_pp Script era
_script = Integer -> Coin
Coin Integer
0
genEraDone :: UTxO era -> PParams era -> Tx era -> Gen (Tx era)
genEraDone UTxO era
_utxo PParams era
_pp Tx era
x = Tx era -> Gen (Tx era)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Tx era
x
genEraTweakBlock :: PParams era -> Seq (Tx era) -> Gen (Seq (Tx era))
genEraTweakBlock PParams era
_pp Seq (Tx era)
seqTx = Seq (Tx era) -> Gen (Seq (Tx era))
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq (Tx era)
seqTx
hasFailedScripts :: Tx era -> Bool
hasFailedScripts = Bool -> Tx era -> Bool
forall a b. a -> b -> a
const Bool
False
feeOrCollateral :: Tx era -> UTxO era -> Coin
feeOrCollateral Tx era
tx UTxO era
_ = Tx era
tx Tx era -> Getting Coin (Tx era) Coin -> Coin
forall s a. s -> Getting a s a -> a
^. (TxBody era -> Const Coin (TxBody era))
-> Tx era -> Const Coin (Tx era)
forall era. EraTx era => Lens' (Tx era) (TxBody era)
Lens' (Tx era) (TxBody era)
bodyTxL ((TxBody era -> Const Coin (TxBody era))
-> Tx era -> Const Coin (Tx era))
-> ((Coin -> Const Coin Coin)
-> TxBody era -> Const Coin (TxBody era))
-> Getting Coin (Tx era) Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coin -> Const Coin Coin) -> TxBody era -> Const Coin (TxBody era)
forall era. EraTxBody era => Lens' (TxBody era) Coin
Lens' (TxBody era) Coin
feeTxBodyL
someKeyPairs :: Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs :: Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs Constants
c (Int, Int)
range = Int -> KeyPairs -> KeyPairs
forall a. Int -> [a] -> [a]
take (Int -> KeyPairs -> KeyPairs)
-> Gen Int -> Gen (KeyPairs -> KeyPairs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int, Int)
range Gen (KeyPairs -> KeyPairs) -> Gen KeyPairs -> Gen KeyPairs
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> KeyPairs -> Gen KeyPairs
forall a. [a] -> Gen [a]
shuffle (Constants -> KeyPairs
keyPairs Constants
c)
genUtxo0 :: forall era c. EraGen era => GenEnv c era -> Gen (UTxO era)
genUtxo0 :: forall era c. EraGen era => GenEnv c era -> Gen (UTxO era)
genUtxo0 ge :: GenEnv c era
ge@(GenEnv KeySpace c era
_ ScriptSpace era
_ c :: Constants
c@Constants {Int
minGenesisUTxOouts :: Int
minGenesisUTxOouts :: Constants -> Int
minGenesisUTxOouts, Int
maxGenesisUTxOouts :: Int
maxGenesisUTxOouts :: Constants -> Int
maxGenesisUTxOouts}) = do
let range :: (Int, Int)
range = (Int
minGenesisUTxOouts Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2, Int
maxGenesisUTxOouts Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)
KeyPairs
genesisKeys <- Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs Constants
c (Int, Int)
range
[(Script era, Script era)]
genesisScripts <- forall era.
EraGen era =>
Constants -> (Int, Int) -> Gen [(Script era, Script era)]
someScripts @era Constants
c (Int, Int)
range
[TxOut era]
outs <-
GenEnv c era -> Gen (Value era) -> [Addr] -> Gen [TxOut era]
forall c.
GenEnv c era -> Gen (Value era) -> [Addr] -> Gen [TxOut era]
forall era c.
MinGenTxout era =>
GenEnv c era -> Gen (Value era) -> [Addr] -> Gen [TxOut era]
genEraTxOut GenEnv c era
ge (GenEnv c era -> Gen (Value era)
forall c. GenEnv c era -> Gen (Value era)
forall era c. EraGen era => GenEnv c era -> Gen (Value era)
genGenesisValue GenEnv c era
ge) ([Addr] -> Gen [TxOut era]) -> [Addr] -> Gen [TxOut era]
forall a b. (a -> b) -> a -> b
$
((KeyPair 'Payment, KeyPair 'Staking) -> Addr)
-> KeyPairs -> [Addr]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((KeyPair 'Payment -> KeyPair 'Staking -> Addr)
-> (KeyPair 'Payment, KeyPair 'Staking) -> Addr
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry KeyPair 'Payment -> KeyPair 'Staking -> Addr
forall p s.
(MakeCredential p 'Payment, MakeStakeReference s) =>
p -> s -> Addr
mkAddr) KeyPairs
genesisKeys
[Addr] -> [Addr] -> [Addr]
forall a. [a] -> [a] -> [a]
++ ((Script era, Script era) -> Addr)
-> [(Script era, Script era)] -> [Addr]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ScriptHash -> ScriptHash -> Addr)
-> (ScriptHash, ScriptHash) -> Addr
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ScriptHash -> ScriptHash -> Addr
forall p s.
(MakeCredential p 'Payment, MakeStakeReference s) =>
p -> s -> Addr
mkAddr ((ScriptHash, ScriptHash) -> Addr)
-> ((Script era, Script era) -> (ScriptHash, ScriptHash))
-> (Script era, Script era)
-> Addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Script era -> ScriptHash)
-> (Script era -> ScriptHash)
-> (Script era, Script era)
-> (ScriptHash, ScriptHash)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Script era -> ScriptHash
forall era. EraScript era => Script era -> ScriptHash
hashScript Script era -> ScriptHash
forall era. EraScript era => Script era -> ScriptHash
hashScript) [(Script era, Script era)]
genesisScripts
UTxO era -> Gen (UTxO era)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxId -> [TxOut era] -> UTxO era
forall era. TxId -> [TxOut era] -> UTxO era
genesisCoins TxId
genesisId [TxOut era]
outs)
genesisId :: TxId
genesisId :: TxId
genesisId = SafeHash EraIndependentTxBody -> TxId
TxId (Hash HASH EraIndependentTxBody -> SafeHash EraIndependentTxBody
forall i. Hash HASH i -> SafeHash i
unsafeMakeSafeHash (Int -> Hash HASH EraIndependentTxBody
forall h a b. (HashAlgorithm h, EncCBOR a) => a -> Hash h b
mkDummyHash (Int
0 :: Int)))
someScripts ::
forall era.
EraGen era =>
Constants ->
(Int, Int) ->
Gen [(Script era, Script era)]
someScripts :: forall era.
EraGen era =>
Constants -> (Int, Int) -> Gen [(Script era, Script era)]
someScripts Constants
c (Int, Int)
range = Int -> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Int -> [a] -> [a]
take (Int -> [(Script era, Script era)] -> [(Script era, Script era)])
-> Gen Int
-> Gen ([(Script era, Script era)] -> [(Script era, Script era)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int, Int)
range Gen ([(Script era, Script era)] -> [(Script era, Script era)])
-> Gen [(Script era, Script era)] -> Gen [(Script era, Script era)]
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [(Script era, Script era)] -> Gen [(Script era, Script era)]
forall a. [a] -> Gen [a]
shuffle (forall era. EraGen era => Constants -> [(Script era, Script era)]
allScripts @era Constants
c)
allScripts :: forall era. EraGen era => Constants -> [(Script era, Script era)]
allScripts :: forall era. EraGen era => Constants -> [(Script era, Script era)]
allScripts Constants
c =
[[(Script era, Script era)]] -> [(Script era, Script era)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [(Script era, Script era)]
plutusPairs
, Int -> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Int -> [a] -> [a]
take (Constants -> Int
numSimpleScripts Constants
c) [(Script era, Script era)]
simpleScripts
, forall era.
ScriptClass era =>
Constants -> [(Script era, Script era)]
combinedScripts @era Constants
c
]
where
simpleScripts :: [(Script era, Script era)]
simpleScripts = forall era.
ScriptClass era =>
Constants -> [(Script era, Script era)]
baseScripts @era Constants
c
plutusPairs :: [(Script era, Script era)]
plutusPairs :: [(Script era, Script era)]
plutusPairs = do
Script era
script3 <- TwoPhase3ArgInfo era -> Script era
forall era. TwoPhase3ArgInfo era -> Script era
getScript3 (TwoPhase3ArgInfo era -> Script era)
-> [TwoPhase3ArgInfo era] -> [Script era]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TwoPhase3ArgInfo era]
forall era. EraGen era => [TwoPhase3ArgInfo era]
genEraTwoPhase3Arg
Script era
script2 <- TwoPhase2ArgInfo era -> Script era
forall era. TwoPhase2ArgInfo era -> Script era
getScript2 (TwoPhase2ArgInfo era -> Script era)
-> [TwoPhase2ArgInfo era] -> [Script era]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TwoPhase2ArgInfo era]
forall era. EraGen era => [TwoPhase2ArgInfo era]
genEraTwoPhase2Arg
(Script era
payment, Script era
staking) <- Int -> [(Script era, Script era)] -> [(Script era, Script era)]
forall a. Int -> [a] -> [a]
take Int
3 [(Script era, Script era)]
simpleScripts
[(Script era
script3, Script era
staking), (Script era
payment, Script era
script2), (Script era
script3, Script era
script2)]
data Label t where
Body' :: Label (TxBody era)
Wits' :: Label (TxWits era)
class Sets (x :: Label t) y where
set :: Label t -> y -> y