{-# 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.BaseTypes (Network (..), ShelleyBase, StrictMaybe)
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Core
import Cardano.Ledger.Hashes (unsafeMakeSafeHash)
import Cardano.Ledger.Keys (WitVKey)
import Cardano.Ledger.Shelley.API (
Addr (Addr),
Block (..),
Credential (ScriptHashObj),
LedgerEnv,
LedgerState,
ShelleyLedgersEnv,
StakeReference (StakeRefBase),
)
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.TxIn (TxId (TxId), TxIn)
import Cardano.Ledger.UTxO (UTxO)
import Cardano.Protocol.TPraos.BHeader (BHeader)
import Cardano.Slotting.Slot (SlotNo)
import Control.State.Transition.Extended (STS (..))
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 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)
) =>
EraGen era
where
genGenesisValue :: GenEnv era -> Gen (Value era)
genEraTwoPhase3Arg :: [TwoPhase3ArgInfo era]
genEraTwoPhase3Arg = []
genEraTwoPhase2Arg :: [TwoPhase2ArgInfo era]
genEraTwoPhase2Arg = []
genEraTxBody ::
GenEnv 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 =
forall era. EraTx era => TxBody era -> Tx era
mkBasicTx TxBody era
txBody forall a b. a -> (a -> b) -> b
& forall era. EraTx era => Lens' (Tx era) (TxWits era)
witsTxL forall s t a b. ASetter s t a b -> b -> s -> t
.~ TxWits era
txWits forall a b. a -> (a -> b) -> b
& forall era.
EraTx era =>
Lens' (Tx era) (StrictMaybe (TxAuxData era))
auxDataTxL 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 = 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 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq (Tx era)
seqTx
hasFailedScripts :: Tx era -> Bool
hasFailedScripts = forall a b. a -> b -> a
const Bool
False
feeOrCollateral :: Tx era -> UTxO era -> Coin
feeOrCollateral Tx era
tx UTxO era
_ = Tx era
tx forall s a. s -> Getting a s a -> a
^. forall era. EraTx era => Lens' (Tx era) (TxBody era)
bodyTxL forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era. EraTxBody era => Lens' (TxBody era) Coin
feeTxBodyL
someKeyPairs :: Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs :: Constants -> (Int, Int) -> Gen KeyPairs
someKeyPairs Constants
c (Int, Int)
range = forall a. Int -> [a] -> [a]
take forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => (a, a) -> Gen a
choose (Int, Int)
range forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. [a] -> Gen [a]
shuffle (Constants -> KeyPairs
keyPairs Constants
c)
genUtxo0 :: forall era. EraGen era => GenEnv era -> Gen (UTxO era)
genUtxo0 :: forall era. EraGen era => GenEnv era -> Gen (UTxO era)
genUtxo0 ge :: GenEnv era
ge@(GenEnv KeySpace era
_ ScriptSpace era
_ c :: Constants
c@Constants {Int
minGenesisUTxOouts :: Constants -> Int
minGenesisUTxOouts :: Int
minGenesisUTxOouts, Int
maxGenesisUTxOouts :: Constants -> Int
maxGenesisUTxOouts :: Int
maxGenesisUTxOouts}) = do
let range :: (Int, Int)
range = (Int
minGenesisUTxOouts forall a. Integral a => a -> a -> a
`div` Int
2, Int
maxGenesisUTxOouts 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 <-
(forall era.
MinGenTxout era =>
GenEnv era -> Gen (Value era) -> [Addr] -> Gen [TxOut era]
genEraTxOut @era GenEnv era
ge)
(forall era. EraGen era => GenEnv era -> Gen (Value era)
genGenesisValue @era GenEnv era
ge)
(forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KeyPair 'Payment, KeyPair 'Staking) -> Addr
mkAddr KeyPairs
genesisKeys forall a. [a] -> [a] -> [a]
++ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Network -> (Script era, Script era) -> Addr
scriptsmkAddr' Network
Testnet) [(Script era, Script era)]
genesisScripts)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall era. TxId -> [TxOut era] -> UTxO era
genesisCoins TxId
genesisId [TxOut era]
outs)
where
scriptsmkAddr' :: Network -> (Script era, Script era) -> Addr
scriptsmkAddr' :: Network -> (Script era, Script era) -> Addr
scriptsmkAddr' Network
n (Script era
payScript, Script era
stakeScript) =
Network -> PaymentCredential -> StakeReference -> Addr
Addr Network
n (forall (kr :: KeyRole). Script era -> Credential kr
scriptToCred' Script era
payScript) (StakeCredential -> StakeReference
StakeRefBase forall a b. (a -> b) -> a -> b
$ forall (kr :: KeyRole). Script era -> Credential kr
scriptToCred' Script era
stakeScript)
scriptToCred' :: Script era -> Credential kr
scriptToCred' :: forall (kr :: KeyRole). Script era -> Credential kr
scriptToCred' = forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era. EraScript era => Script era -> ScriptHash
hashScript @era
genesisId :: TxId
genesisId :: TxId
genesisId = SafeHash EraIndependentTxBody -> TxId
TxId (forall i. Hash HASH i -> SafeHash i
unsafeMakeSafeHash (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 = forall a. Int -> [a] -> [a]
take forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => (a, a) -> Gen a
choose (Int, Int)
range forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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 =
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [(Script era, Script era)]
plutusPairs
, 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 <- forall era. TwoPhase3ArgInfo era -> Script era
getScript3 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era. EraGen era => [TwoPhase3ArgInfo era]
genEraTwoPhase3Arg
Script era
script2 <- forall era. TwoPhase2ArgInfo era -> Script era
getScript2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall era. EraGen era => [TwoPhase2ArgInfo era]
genEraTwoPhase2Arg
(Script era
payment, Script era
staking) <- 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