{-# 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 qualified Cardano.Crypto.Hash as Hash
import Cardano.Ledger.AuxiliaryData (AuxiliaryDataHash)
import Cardano.Ledger.BaseTypes (Network (..), ShelleyBase, StrictMaybe)
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Core
import qualified Cardano.Ledger.Crypto as CC (Crypto, HASH)
import Cardano.Ledger.Keys (KeyRole (Witness), WitVKey)
import Cardano.Ledger.SafeHash (unsafeMakeSafeHash)
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.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 (EraCrypto era)) 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 (EraCrypto era)] -> 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 (EraCrypto era)) ->
StrictSeq (TxOut era) ->
StrictSeq (TxCert era) ->
Withdrawals (EraCrypto era) ->
Coin ->
StrictMaybe (Update era) ->
StrictMaybe (AuxiliaryDataHash (EraCrypto era)) ->
Gen (TxBody era, [Script era])
genEraAuxiliaryData :: Constants -> Gen (StrictMaybe (TxAuxData era))
updateEraTxBody ::
UTxO era ->
PParams era ->
TxWits era ->
TxBody era ->
Coin ->
Set (TxIn (EraCrypto era)) ->
TxOut era ->
TxBody era
addInputs :: TxBody era -> Set (TxIn (EraCrypto era)) -> TxBody era
addInputs TxBody era
txb Set (TxIn (EraCrypto era))
_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 (EraCrypto era)) ->
Map (ScriptHash (EraCrypto era)) (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 :: CC.Crypto c => Constants -> (Int, Int) -> Gen (KeyPairs c)
someKeyPairs :: forall c. Crypto c => Constants -> (Int, Int) -> Gen (KeyPairs c)
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 (forall c. Crypto c => Constants -> KeyPairs c
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 (EraCrypto era)
genesisKeys <- forall c. Crypto c => Constants -> (Int, Int) -> Gen (KeyPairs c)
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 (EraCrypto era)] -> 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 forall c.
Crypto c =>
(KeyPair 'Payment c, KeyPair 'Staking c) -> Addr c
mkAddr KeyPairs (EraCrypto era)
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 (EraCrypto era)
scriptsmkAddr' Network
Testnet) [(Script era, Script era)]
genesisScripts)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall era. TxId (EraCrypto era) -> [TxOut era] -> UTxO era
genesisCoins forall c. HashAlgorithm (HASH c) => TxId c
genesisId [TxOut era]
outs)
where
scriptsmkAddr' :: Network -> (Script era, Script era) -> Addr (EraCrypto era)
scriptsmkAddr' :: Network -> (Script era, Script era) -> Addr (EraCrypto era)
scriptsmkAddr' Network
n (Script era
payScript, Script era
stakeScript) =
forall c.
Network -> PaymentCredential c -> StakeReference c -> Addr c
Addr Network
n (forall (kr :: KeyRole). Script era -> Credential kr (EraCrypto era)
scriptToCred' Script era
payScript) (forall c. StakeCredential c -> StakeReference c
StakeRefBase forall a b. (a -> b) -> a -> b
$ forall (kr :: KeyRole). Script era -> Credential kr (EraCrypto era)
scriptToCred' Script era
stakeScript)
scriptToCred' :: Script era -> Credential kr (EraCrypto era)
scriptToCred' :: forall (kr :: KeyRole). Script era -> Credential kr (EraCrypto era)
scriptToCred' = forall (kr :: KeyRole) c. ScriptHash c -> Credential kr c
ScriptHashObj forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era.
EraScript era =>
Script era -> ScriptHash (EraCrypto era)
hashScript @era
genesisId ::
Hash.HashAlgorithm (CC.HASH c) =>
TxId c
genesisId :: forall c. HashAlgorithm (HASH c) => TxId c
genesisId = forall c. SafeHash c EraIndependentTxBody -> TxId c
TxId (forall c index. Hash (HASH c) index -> SafeHash c index
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