module Hydra.Generator where

import Hydra.Cardano.Api
import Hydra.Prelude hiding (size)

import Cardano.Api.UTxO qualified as UTxO
import CardanoClient (mkGenesisTx)
import Control.Monad (foldM)
import Data.Default (def)
import Hydra.Cluster.Fixture (Actor (Faucet), availableInitialFunds)
import Hydra.Cluster.Util (keysFor)
import Hydra.Ledger.Cardano (genSigningKey, generateOneTransfer)
import Test.QuickCheck (choose, generate, sized)

networkId :: NetworkId
networkId :: NetworkId
networkId = NetworkMagic -> NetworkId
Testnet (NetworkMagic -> NetworkId) -> NetworkMagic -> NetworkId
forall a b. (a -> b) -> a -> b
$ Word32 -> NetworkMagic
NetworkMagic Word32
42

-- | A 'Dataset' that can be run for testing purpose.
-- Each `Dataset` represents a complete scenario where several `ClientDataset` are run concurrently
-- against one or more `HydraNode`s. A dataset can optionally have a `title` and `description`
-- which will be used to report results.
data Dataset = Dataset
  { Dataset -> Tx
fundingTransaction :: Tx
  , Dataset -> [ClientDataset]
clientDatasets :: [ClientDataset]
  , Dataset -> Maybe Text
title :: Maybe Text
  , Dataset -> Maybe Text
description :: Maybe Text
  }
  deriving stock (Int -> Dataset -> ShowS
[Dataset] -> ShowS
Dataset -> String
(Int -> Dataset -> ShowS)
-> (Dataset -> String) -> ([Dataset] -> ShowS) -> Show Dataset
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Dataset -> ShowS
showsPrec :: Int -> Dataset -> ShowS
$cshow :: Dataset -> String
show :: Dataset -> String
$cshowList :: [Dataset] -> ShowS
showList :: [Dataset] -> ShowS
Show, (forall x. Dataset -> Rep Dataset x)
-> (forall x. Rep Dataset x -> Dataset) -> Generic Dataset
forall x. Rep Dataset x -> Dataset
forall x. Dataset -> Rep Dataset x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Dataset -> Rep Dataset x
from :: forall x. Dataset -> Rep Dataset x
$cto :: forall x. Rep Dataset x -> Dataset
to :: forall x. Rep Dataset x -> Dataset
Generic)

instance ToCBOR Dataset where
  toCBOR :: Dataset -> Encoding
toCBOR Dataset{Tx
fundingTransaction :: Dataset -> Tx
fundingTransaction :: Tx
fundingTransaction, [ClientDataset]
clientDatasets :: Dataset -> [ClientDataset]
clientDatasets :: [ClientDataset]
clientDatasets, Maybe Text
title :: Dataset -> Maybe Text
title :: Maybe Text
title, Maybe Text
description :: Dataset -> Maybe Text
description :: Maybe Text
description} =
    [Encoding] -> Encoding
forall a. Monoid a => [a] -> a
mconcat
      [ Tx -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Tx
fundingTransaction
      , [ClientDataset] -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR [ClientDataset]
clientDatasets
      , Maybe Text -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Maybe Text
title
      , Maybe Text -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Maybe Text
description
      ]

instance FromCBOR Dataset where
  fromCBOR :: forall s. Decoder s Dataset
fromCBOR = Tx -> [ClientDataset] -> Maybe Text -> Maybe Text -> Dataset
Dataset (Tx -> [ClientDataset] -> Maybe Text -> Maybe Text -> Dataset)
-> Decoder s Tx
-> Decoder
     s ([ClientDataset] -> Maybe Text -> Maybe Text -> Dataset)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Tx
forall s. Decoder s Tx
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s ([ClientDataset] -> Maybe Text -> Maybe Text -> Dataset)
-> Decoder s [ClientDataset]
-> Decoder s (Maybe Text -> Maybe Text -> Dataset)
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s [ClientDataset]
forall s. Decoder s [ClientDataset]
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s (Maybe Text -> Maybe Text -> Dataset)
-> Decoder s (Maybe Text) -> Decoder s (Maybe Text -> Dataset)
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s (Maybe Text)
forall s. Decoder s (Maybe Text)
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s (Maybe Text -> Dataset)
-> Decoder s (Maybe Text) -> Decoder s Dataset
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s (Maybe Text)
forall s. Decoder s (Maybe Text)
forall a s. FromCBOR a => Decoder s a
fromCBOR

instance Arbitrary Dataset where
  arbitrary :: Gen Dataset
arbitrary = (Int -> Gen Dataset) -> Gen Dataset
forall a. (Int -> Gen a) -> Gen a
sized ((Int -> Gen Dataset) -> Gen Dataset)
-> (Int -> Gen Dataset) -> Gen Dataset
forall a b. (a -> b) -> a -> b
$ \Int
n -> do
    SigningKey PaymentKey
sk <- Gen (SigningKey PaymentKey)
genSigningKey
    SigningKey PaymentKey
-> ProtocolParameters -> Int -> Int -> Gen Dataset
genDatasetConstantUTxO SigningKey PaymentKey
sk ProtocolParameters
defaultProtocolParameters (Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
10) Int
n

data ClientKeys = ClientKeys
  { ClientKeys -> SigningKey PaymentKey
signingKey :: SigningKey PaymentKey
  -- ^ Key used by the hydra-node to authorize hydra transactions and holding fuel.
  , ClientKeys -> SigningKey PaymentKey
externalSigningKey :: SigningKey PaymentKey
  -- ^ Key holding funds to commit.
  }
  deriving stock (Int -> ClientKeys -> ShowS
[ClientKeys] -> ShowS
ClientKeys -> String
(Int -> ClientKeys -> ShowS)
-> (ClientKeys -> String)
-> ([ClientKeys] -> ShowS)
-> Show ClientKeys
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClientKeys -> ShowS
showsPrec :: Int -> ClientKeys -> ShowS
$cshow :: ClientKeys -> String
show :: ClientKeys -> String
$cshowList :: [ClientKeys] -> ShowS
showList :: [ClientKeys] -> ShowS
Show)

instance Arbitrary ClientKeys where
  arbitrary :: Gen ClientKeys
arbitrary = SigningKey PaymentKey -> SigningKey PaymentKey -> ClientKeys
ClientKeys (SigningKey PaymentKey -> SigningKey PaymentKey -> ClientKeys)
-> Gen (SigningKey PaymentKey)
-> Gen (SigningKey PaymentKey -> ClientKeys)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (SigningKey PaymentKey)
genSigningKey Gen (SigningKey PaymentKey -> ClientKeys)
-> Gen (SigningKey PaymentKey) -> Gen ClientKeys
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (SigningKey PaymentKey)
genSigningKey

instance ToCBOR ClientKeys where
  toCBOR :: ClientKeys -> Encoding
toCBOR ClientKeys{SigningKey PaymentKey
signingKey :: ClientKeys -> SigningKey PaymentKey
signingKey :: SigningKey PaymentKey
signingKey, SigningKey PaymentKey
externalSigningKey :: ClientKeys -> SigningKey PaymentKey
externalSigningKey :: SigningKey PaymentKey
externalSigningKey} =
    [Encoding] -> Encoding
forall a. Monoid a => [a] -> a
mconcat
      [ SigningKey PaymentKey -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR SigningKey PaymentKey
signingKey
      , SigningKey PaymentKey -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR SigningKey PaymentKey
externalSigningKey
      ]

instance FromCBOR ClientKeys where
  fromCBOR :: forall s. Decoder s ClientKeys
fromCBOR = SigningKey PaymentKey -> SigningKey PaymentKey -> ClientKeys
ClientKeys (SigningKey PaymentKey -> SigningKey PaymentKey -> ClientKeys)
-> Decoder s (SigningKey PaymentKey)
-> Decoder s (SigningKey PaymentKey -> ClientKeys)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s (SigningKey PaymentKey)
forall s. Decoder s (SigningKey PaymentKey)
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s (SigningKey PaymentKey -> ClientKeys)
-> Decoder s (SigningKey PaymentKey) -> Decoder s ClientKeys
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s (SigningKey PaymentKey)
forall s. Decoder s (SigningKey PaymentKey)
forall a s. FromCBOR a => Decoder s a
fromCBOR

data ClientDataset = ClientDataset
  { ClientDataset -> ClientKeys
clientKeys :: ClientKeys
  , ClientDataset -> UTxO
initialUTxO :: UTxO
  , ClientDataset -> [Tx]
txSequence :: [Tx]
  }
  deriving stock (Int -> ClientDataset -> ShowS
[ClientDataset] -> ShowS
ClientDataset -> String
(Int -> ClientDataset -> ShowS)
-> (ClientDataset -> String)
-> ([ClientDataset] -> ShowS)
-> Show ClientDataset
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClientDataset -> ShowS
showsPrec :: Int -> ClientDataset -> ShowS
$cshow :: ClientDataset -> String
show :: ClientDataset -> String
$cshowList :: [ClientDataset] -> ShowS
showList :: [ClientDataset] -> ShowS
Show, (forall x. ClientDataset -> Rep ClientDataset x)
-> (forall x. Rep ClientDataset x -> ClientDataset)
-> Generic ClientDataset
forall x. Rep ClientDataset x -> ClientDataset
forall x. ClientDataset -> Rep ClientDataset x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ClientDataset -> Rep ClientDataset x
from :: forall x. ClientDataset -> Rep ClientDataset x
$cto :: forall x. Rep ClientDataset x -> ClientDataset
to :: forall x. Rep ClientDataset x -> ClientDataset
Generic)

instance ToCBOR ClientDataset where
  toCBOR :: ClientDataset -> Encoding
toCBOR ClientDataset{ClientKeys
clientKeys :: ClientDataset -> ClientKeys
clientKeys :: ClientKeys
clientKeys, UTxO
initialUTxO :: ClientDataset -> UTxO
initialUTxO :: UTxO
initialUTxO, [Tx]
txSequence :: ClientDataset -> [Tx]
txSequence :: [Tx]
txSequence} =
    [Encoding] -> Encoding
forall a. Monoid a => [a] -> a
mconcat
      [ ClientKeys -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR ClientKeys
clientKeys
      , UTxO -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR UTxO
initialUTxO
      , [Tx] -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR [Tx]
txSequence
      ]

instance FromCBOR ClientDataset where
  fromCBOR :: forall s. Decoder s ClientDataset
fromCBOR = ClientKeys -> UTxO -> [Tx] -> ClientDataset
ClientDataset (ClientKeys -> UTxO -> [Tx] -> ClientDataset)
-> Decoder s ClientKeys
-> Decoder s (UTxO -> [Tx] -> ClientDataset)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s ClientKeys
forall s. Decoder s ClientKeys
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s (UTxO -> [Tx] -> ClientDataset)
-> Decoder s UTxO -> Decoder s ([Tx] -> ClientDataset)
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s UTxO
forall s. Decoder s UTxO
forall a s. FromCBOR a => Decoder s a
fromCBOR Decoder s ([Tx] -> ClientDataset)
-> Decoder s [Tx] -> Decoder s ClientDataset
forall a b. Decoder s (a -> b) -> Decoder s a -> Decoder s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Decoder s [Tx]
forall s. Decoder s [Tx]
forall a s. FromCBOR a => Decoder s a
fromCBOR

defaultProtocolParameters :: ProtocolParameters
defaultProtocolParameters :: ProtocolParameters
defaultProtocolParameters = ShelleyBasedEra ShelleyEra
-> PParams (ShelleyLedgerEra ShelleyEra) -> ProtocolParameters
forall era.
ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> ProtocolParameters
fromLedgerPParams ShelleyBasedEra ShelleyEra
ShelleyBasedEraShelley PParams (ShelleyLedgerEra ShelleyEra)
PParams StandardShelley
forall a. Default a => a
def

-- | Generate 'Dataset' which does not grow the per-client UTXO set over time.
-- The sequence of transactions generated consist only of simple payments from
-- and to arbitrary keys controlled by the individual clients.
generateConstantUTxODataset ::
  ProtocolParameters ->
  -- | Number of clients
  Int ->
  -- | Number of transactions
  Int ->
  IO Dataset
generateConstantUTxODataset :: ProtocolParameters -> Int -> Int -> IO Dataset
generateConstantUTxODataset ProtocolParameters
pparams Int
nClients Int
nTxs = do
  (VerificationKey PaymentKey
_, SigningKey PaymentKey
faucetSk) <- Actor -> IO (VerificationKey PaymentKey, SigningKey PaymentKey)
keysFor Actor
Faucet
  Gen Dataset -> IO Dataset
forall a. Gen a -> IO a
generate (Gen Dataset -> IO Dataset) -> Gen Dataset -> IO Dataset
forall a b. (a -> b) -> a -> b
$ SigningKey PaymentKey
-> ProtocolParameters -> Int -> Int -> Gen Dataset
genDatasetConstantUTxO SigningKey PaymentKey
faucetSk ProtocolParameters
pparams Int
nClients Int
nTxs

genDatasetConstantUTxO ::
  -- | The faucet signing key
  SigningKey PaymentKey ->
  ProtocolParameters ->
  -- | Number of clients
  Int ->
  -- | Number of transactions
  Int ->
  Gen Dataset
genDatasetConstantUTxO :: SigningKey PaymentKey
-> ProtocolParameters -> Int -> Int -> Gen Dataset
genDatasetConstantUTxO SigningKey PaymentKey
faucetSk ProtocolParameters
pparams Int
nClients Int
nTxs = do
  [ClientKeys]
clientKeys <- Int -> Gen ClientKeys -> Gen [ClientKeys]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
nClients Gen ClientKeys
forall a. Arbitrary a => Gen a
arbitrary
  -- Prepare funding transaction which will give every client's
  -- 'externalSigningKey' "some" lovelace. The internal 'signingKey' will get
  -- funded in the beginning of the benchmark run.
  [(VerificationKey PaymentKey, Coin)]
clientFunds <- [ClientKeys]
-> (ClientKeys -> Gen (VerificationKey PaymentKey, Coin))
-> Gen [(VerificationKey PaymentKey, Coin)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [ClientKeys]
clientKeys ((ClientKeys -> Gen (VerificationKey PaymentKey, Coin))
 -> Gen [(VerificationKey PaymentKey, Coin)])
-> (ClientKeys -> Gen (VerificationKey PaymentKey, Coin))
-> Gen [(VerificationKey PaymentKey, Coin)]
forall a b. (a -> b) -> a -> b
$ \ClientKeys{SigningKey PaymentKey
externalSigningKey :: ClientKeys -> SigningKey PaymentKey
externalSigningKey :: SigningKey PaymentKey
externalSigningKey} -> do
    Coin
amount <- Integer -> Coin
Coin (Integer -> Coin) -> Gen Integer -> Gen Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
choose (Integer
1, Integer
forall a. Num a => a
availableInitialFunds Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nClients)
    (VerificationKey PaymentKey, Coin)
-> Gen (VerificationKey PaymentKey, Coin)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SigningKey PaymentKey -> VerificationKey PaymentKey
forall keyrole.
(Key keyrole, HasTypeProxy keyrole) =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey PaymentKey
externalSigningKey, Coin
amount)
  let fundingTransaction :: Tx
fundingTransaction =
        NetworkId
-> ProtocolParameters
-> SigningKey PaymentKey
-> Coin
-> [(VerificationKey PaymentKey, Coin)]
-> Tx
mkGenesisTx
          NetworkId
networkId
          ProtocolParameters
pparams
          SigningKey PaymentKey
faucetSk
          (Integer -> Coin
Coin Integer
forall a. Num a => a
availableInitialFunds)
          [(VerificationKey PaymentKey, Coin)]
clientFunds
  [ClientDataset]
clientDatasets <- [ClientKeys]
-> (ClientKeys -> Gen ClientDataset) -> Gen [ClientDataset]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [ClientKeys]
clientKeys (Tx -> ClientKeys -> Gen ClientDataset
generateClientDataset Tx
fundingTransaction)
  Dataset -> Gen Dataset
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Dataset{Tx
fundingTransaction :: Tx
fundingTransaction :: Tx
fundingTransaction, [ClientDataset]
clientDatasets :: [ClientDataset]
clientDatasets :: [ClientDataset]
clientDatasets, title :: Maybe Text
title = Maybe Text
forall a. Maybe a
Nothing, description :: Maybe Text
description = Maybe Text
forall a. Maybe a
Nothing}
 where
  generateClientDataset :: Tx -> ClientKeys -> Gen ClientDataset
generateClientDataset Tx
fundingTransaction clientKeys :: ClientKeys
clientKeys@ClientKeys{SigningKey PaymentKey
externalSigningKey :: ClientKeys -> SigningKey PaymentKey
externalSigningKey :: SigningKey PaymentKey
externalSigningKey} = do
    let vk :: VerificationKey PaymentKey
vk = SigningKey PaymentKey -> VerificationKey PaymentKey
forall keyrole.
(Key keyrole, HasTypeProxy keyrole) =>
SigningKey keyrole -> VerificationKey keyrole
getVerificationKey SigningKey PaymentKey
externalSigningKey
        keyPair :: (VerificationKey PaymentKey, SigningKey PaymentKey)
keyPair = (VerificationKey PaymentKey
vk, SigningKey PaymentKey
externalSigningKey)
        -- NOTE: The initialUTxO must all UTXO we will later commit. We assume
        -- that everything owned by the externalSigningKey will get committed
        -- into the head.
        initialUTxO :: UTxO
initialUTxO =
          Tx -> UTxO
utxoProducedByTx Tx
fundingTransaction
            UTxO -> (UTxO -> UTxO) -> UTxO
forall a b. a -> (a -> b) -> b
& (TxOut CtxUTxO Era -> Bool) -> UTxO -> UTxO
forall out. (out -> Bool) -> UTxO' out -> UTxO' out
UTxO.filter ((AddressInEra Era -> AddressInEra Era -> Bool
forall a. Eq a => a -> a -> Bool
== NetworkId -> VerificationKey PaymentKey -> AddressInEra Era
forall era.
IsShelleyBasedEra era =>
NetworkId -> VerificationKey PaymentKey -> AddressInEra era
mkVkAddress NetworkId
networkId VerificationKey PaymentKey
vk) (AddressInEra Era -> Bool)
-> (TxOut CtxUTxO Era -> AddressInEra Era)
-> TxOut CtxUTxO Era
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxOut CtxUTxO Era -> AddressInEra Era
forall ctx. TxOut ctx -> AddressInEra Era
txOutAddress)
    [Tx]
txSequence <-
      [Tx] -> [Tx]
forall a. [a] -> [a]
reverse
        ([Tx] -> [Tx])
-> ((UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey),
     [Tx])
    -> [Tx])
-> (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey),
    [Tx])
-> [Tx]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
-> [Tx]
forall {a} {b} {c}. (a, b, c) -> c
thrd
        ((UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
 -> [Tx])
-> Gen
     (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
-> Gen [Tx]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
 -> Int
 -> Gen
      (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx]))
-> (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey),
    [Tx])
-> [Int]
-> Gen
     (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (NetworkId
-> (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey),
    [Tx])
-> Int
-> Gen
     (UTxO, (VerificationKey PaymentKey, SigningKey PaymentKey), [Tx])
generateOneTransfer NetworkId
networkId) (UTxO
initialUTxO, (VerificationKey PaymentKey, SigningKey PaymentKey)
keyPair, []) [Int
1 .. Int
nTxs]
    ClientDataset -> Gen ClientDataset
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ClientDataset{ClientKeys
clientKeys :: ClientKeys
clientKeys :: ClientKeys
clientKeys, UTxO
initialUTxO :: UTxO
initialUTxO :: UTxO
initialUTxO, [Tx]
txSequence :: [Tx]
txSequence :: [Tx]
txSequence}

  thrd :: (a, b, c) -> c
thrd (a
_, b
_, c
c) = c
c