{-# 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 TopTx 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 TopTx 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 TopTx era
, State (EraRule "UTXO" era) ~ UTxOState era
, Environment (EraRule "UTXO" era) ~ UtxoEnv era
, Signal (EraRule "UTXO" era) ~ Tx TopTx 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
( EraBlockBody 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 TopTx era, [Script era])
genEraAuxiliaryData :: Constants -> Gen (StrictMaybe (TxAuxData era))
updateEraTxBody ::
UTxO era ->
PParams era ->
TxWits era ->
TxBody TopTx era ->
Coin ->
Set TxIn ->
TxOut era ->
TxBody TopTx era
addInputs :: TxBody TopTx era -> Set TxIn -> TxBody TopTx era
addInputs TxBody TopTx era
txb Set TxIn
_ins = TxBody TopTx era
txb
genEraPParamsUpdate :: Constants -> PParams era -> Gen (PParamsUpdate era)
genEraPParams :: Constants -> Gen (PParams era)
genEraTxWits ::
(UTxO era, TxBody TopTx era, ScriptInfo era) ->
Set (WitVKey Witness) ->
Map ScriptHash (Script era) ->
TxWits era
genEraGoodTxOut :: TxOut era -> Bool
genEraGoodTxOut TxOut era
_ = Bool
True
constructTx ::
TxBody TopTx era ->
TxWits era ->
StrictMaybe (TxAuxData era) ->
Tx TopTx era
constructTx TxBody TopTx era
txBody TxWits era
txWits StrictMaybe (TxAuxData era)
txAuxData =
TxBody TopTx era -> Tx TopTx era
forall era (l :: TxLevel). EraTx era => TxBody l era -> Tx l era
forall (l :: TxLevel). TxBody l era -> Tx l era
mkBasicTx TxBody TopTx era
txBody Tx TopTx era -> (Tx TopTx era -> Tx TopTx era) -> Tx TopTx era
forall a b. a -> (a -> b) -> b
& (TxWits era -> Identity (TxWits era))
-> Tx TopTx era -> Identity (Tx TopTx era)
forall era (l :: TxLevel).
EraTx era =>
Lens' (Tx l era) (TxWits era)
forall (l :: TxLevel). Lens' (Tx l era) (TxWits era)
witsTxL ((TxWits era -> Identity (TxWits era))
-> Tx TopTx era -> Identity (Tx TopTx era))
-> TxWits era -> Tx TopTx era -> Tx TopTx era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ TxWits era
txWits Tx TopTx era -> (Tx TopTx era -> Tx TopTx era) -> Tx TopTx era
forall a b. a -> (a -> b) -> b
& (StrictMaybe (TxAuxData era)
-> Identity (StrictMaybe (TxAuxData era)))
-> Tx TopTx era -> Identity (Tx TopTx era)
forall era (l :: TxLevel).
EraTx era =>
Lens' (Tx l era) (StrictMaybe (TxAuxData era))
forall (l :: TxLevel).
Lens' (Tx l era) (StrictMaybe (TxAuxData era))
auxDataTxL ((StrictMaybe (TxAuxData era)
-> Identity (StrictMaybe (TxAuxData era)))
-> Tx TopTx era -> Identity (Tx TopTx era))
-> StrictMaybe (TxAuxData era) -> Tx TopTx era -> Tx TopTx 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 TopTx era -> Gen (Tx TopTx era)
genEraDone UTxO era
_utxo PParams era
_pp Tx TopTx era
x = Tx TopTx era -> Gen (Tx TopTx era)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Tx TopTx era
x
genEraTweakBlock :: PParams era -> Seq (Tx TopTx era) -> Gen (Seq (Tx TopTx era))
genEraTweakBlock PParams era
_pp Seq (Tx TopTx era)
seqTx = Seq (Tx TopTx era) -> Gen (Seq (Tx TopTx era))
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq (Tx TopTx era)
seqTx
hasFailedScripts :: Tx TopTx era -> Bool
hasFailedScripts = Bool -> Tx TopTx era -> Bool
forall a b. a -> b -> a
const Bool
False
feeOrCollateral :: Tx TopTx era -> UTxO era -> Coin
feeOrCollateral Tx TopTx era
tx UTxO era
_ = Tx TopTx era
tx Tx TopTx era -> Getting Coin (Tx TopTx era) Coin -> Coin
forall s a. s -> Getting a s a -> a
^. (TxBody TopTx era -> Const Coin (TxBody TopTx era))
-> Tx TopTx era -> Const Coin (Tx TopTx era)
forall era (l :: TxLevel).
EraTx era =>
Lens' (Tx l era) (TxBody l era)
forall (l :: TxLevel). Lens' (Tx l era) (TxBody l era)
bodyTxL ((TxBody TopTx era -> Const Coin (TxBody TopTx era))
-> Tx TopTx era -> Const Coin (Tx TopTx era))
-> ((Coin -> Const Coin Coin)
-> TxBody TopTx era -> Const Coin (TxBody TopTx era))
-> Getting Coin (Tx TopTx era) Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coin -> Const Coin Coin)
-> TxBody TopTx era -> Const Coin (TxBody TopTx era)
forall era. EraTxBody era => Lens' (TxBody TopTx era) Coin
Lens' (TxBody TopTx 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)
genesisKeys <- Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs Constants
c (Int, Int)
range
genesisScripts <- someScripts @era c range
outs <-
genEraTxOut ge (genGenesisValue ge) $
fmap (uncurry mkAddr) genesisKeys
++ fmap (uncurry mkAddr . bimap hashScript hashScript) genesisScripts
return (genesisCoins genesisId 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
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
script2 <- getScript2 <$> genEraTwoPhase2Arg
(payment, staking) <- take 3 simpleScripts
[(script3, staking), (payment, script2), (script3, script2)]
data Label t where
Body' :: Label (TxBody TopTx era)
Wits' :: Label (TxWits era)
class Sets (x :: Label t) y where
set :: Label t -> y -> y