Skip to content

Commit

Permalink
Add pure example with 'demo :: IO ()'
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcFontaine committed Jul 14, 2022
1 parent 9c049c4 commit 86c3af2
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 18 deletions.
4 changes: 2 additions & 2 deletions bench/tx-generator/src/Cardano/Benchmarking/FundSet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ liftAnyEra f x = case x of
InAnyCardanoEra BabbageEra a -> InAnyCardanoEra BabbageEra $ f a

type FundSelector = FundSet -> Either String [Fund]
type FundSource = IO (Either String [Fund])
type FundToStore = [Fund] -> IO ()
type FundSource m = m (Either String [Fund])
type FundToStore m = [Fund] -> m ()

-- Select Funds to cover a minimum value.
-- TODO:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mkBufferedSource ::
-> Lovelace
-> Variant
-> Int
-> IO (Either String FundSource)
-> IO (Either String (FundSource IO))
mkBufferedSource walletRef count minValue variant munch
= mkWalletFundSource walletRef (selectToBuffer count minValue variant) >>= \case
Left err -> return $ Left err
Expand Down
17 changes: 10 additions & 7 deletions bench/tx-generator/src/Cardano/Benchmarking/Script/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,21 @@ readSigningKey name filePath =
Left err -> liftTxGenError err
Right key -> setName name key

defineSigningKey :: KeyName -> TextEnvelope -> ActionM ()
defineSigningKey name descr
= case deserialiseFromTextEnvelopeAnyOf types descr of
Right key -> setName name key
Left err -> throwE $ ApiError $ show err
parseSigningKey :: TextEnvelope -> Either TextEnvelopeError (SigningKey PaymentKey)
parseSigningKey descr = deserialiseFromTextEnvelopeAnyOf types descr
where
types :: [FromSomeType HasTextEnvelope (SigningKey PaymentKey)]
types =
[ FromSomeType (AsSigningKey AsGenesisUTxOKey) castSigningKey
, FromSomeType (AsSigningKey AsPaymentKey) id
]

defineSigningKey :: KeyName -> TextEnvelope -> ActionM ()
defineSigningKey name descr
= case parseSigningKey descr of
Right key -> setName name key
Left err -> throwE $ ApiError $ show err

addFund :: AnyCardanoEra -> WalletName -> TxIn -> Lovelace -> KeyName -> ActionM ()
addFund era wallet txIn lovelace keyName = do
fundKey <- getName keyName
Expand Down Expand Up @@ -514,7 +517,7 @@ createChangeInEra sourceWallet dstWallet submitMode variant keyName value count
protocolParameters <- getProtocolParameters
fundKey <- getName keyName
let
createCoins :: FundSet.FundSource -> [Lovelace] -> ActionM (Either String (TxInMode CardanoMode))
createCoins :: FundSet.FundSource IO -> [Lovelace] -> ActionM (Either String (TxInMode CardanoMode))
createCoins fundSource coins = do
let
-- selector :: FundSet.FundSource
Expand All @@ -535,7 +538,7 @@ createChangeInEra sourceWallet dstWallet submitMode variant keyName value count
createChangeGeneric ::
WalletName
-> SubmitMode
-> (FundSet.FundSource -> [Lovelace] -> ActionM (Either String (TxInMode CardanoMode)))
-> (FundSet.FundSource IO -> [Lovelace] -> ActionM (Either String (TxInMode CardanoMode)))
-> String
-> Lovelace
-> Int
Expand Down
17 changes: 9 additions & 8 deletions bench/tx-generator/src/Cardano/Benchmarking/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,23 @@ walletExtractFunds w s
Left err -> Left err
Right funds -> Right (foldl (flip walletDeleteFund) w funds, funds)

mkWalletFundSource :: WalletRef -> FundSelector -> FundSource
mkWalletFundSource :: WalletRef -> FundSelector -> FundSource IO
mkWalletFundSource walletRef selector
= modifyWalletRefEither walletRef (\wallet -> return $ walletExtractFunds wallet selector)

mkWalletFundStore :: WalletRef -> FundToStore
mkWalletFundStore :: WalletRef -> FundToStore IO
mkWalletFundStore walletRef funds = modifyWalletRef walletRef
$ \wallet -> return (foldl (flip walletInsertFund) wallet funds, ())

--TODO use Error monad
sourceToStoreTransaction ::
TxGenerator era
-> FundSource
Monad m
=> TxGenerator era
-> FundSource m
-> ([Lovelace] -> [Lovelace])
-> ToUTxO era
-> FundToStore
-> IO (Either String (Tx era))
-> FundToStore m
-> m (Either String (Tx era))
sourceToStoreTransaction txGenerator fundSource inToOut mkTxOut fundToStore = do
fundSource >>= \case
Left err -> return $ Left err
Expand Down Expand Up @@ -192,10 +193,10 @@ benchmarkWalletScript :: forall era .
=> WalletRef
-> TxGenerator era
-> NumberOfTxs
-> (Target -> FundSource)
-> (Target -> FundSource IO)
-> ([Lovelace] -> [Lovelace])
-> (Target -> SeqNumber -> ToUTxO era)
-> FundToStore
-> FundToStore IO
-> Target
-> WalletScript era
benchmarkWalletScript wRef txGenerator (NumberOfTxs maxCount) fundSource inOut toUTxO fundToStore targetNode
Expand Down
121 changes: 121 additions & 0 deletions bench/tx-generator/src/Cardano/TxGenerator/PureExample.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
module Cardano.TxGenerator.PureExample
where

import Data.Either (fromRight)
import Data.String (fromString)
import Control.Monad (foldM, void)
import Control.Monad.Trans.State.Strict

import Cardano.Api
import Cardano.Api.Shelley (ProtocolParameters )

import Cardano.Benchmarking.FundSet (Fund (..), FundInEra (..), Validity (..), Variant(..), inputsToOutputsWithFee)
import Cardano.Benchmarking.Script.Aeson (readProtocolParametersFile)
import Cardano.Benchmarking.Script.Core (parseSigningKey)
import Cardano.Benchmarking.Wallet (TxGenerator, genTx, mkUTxOVariant, sourceToStoreTransaction)

import Paths_tx_generator

demo :: IO ()
demo = getDataFileName "data/protocol-parameters.json" >>= demo'

demo' :: FilePath -> IO ()
demo' parametersFile = do
protocolParameters <- readProtocolParametersFile parametersFile
void $ foldM (worker $ generateTx protocolParameters) [genesisFund] [1..10]
where
worker ::
Generator (Either String (Tx BabbageEra))
-> [Fund]
-> Int
-> IO [Fund]
worker pureGenerator generatorState counter = do
putStrLn $ "running tx-generator. Iteration : " ++ show counter
let (res, newState) = runState pureGenerator generatorState
case res of
Right tx -> print tx
Left err -> print err
return newState

signingKey :: SigningKey PaymentKey
signingKey = fromRight (error "signingKey: parseError") $ parseSigningKey keyData
where
keyData = TextEnvelope { teType = TextEnvelopeType "GenesisUTxOSigningKey_ed25519"
, teDescription = fromString "Genesis Initial UTxO Signing Key"
, teRawCBOR = "X \vl1~\182\201v(\152\250A\202\157h0\ETX\248h\153\171\SI/m\186\242D\228\NAK\182(&\162"}

genesisTxIn :: TxIn
genesisValue :: TxOutValue BabbageEra

(genesisTxIn, genesisValue) =
( TxIn "900fc5da77a0747da53f7675cbb7d149d46779346dea2f879ab811ccc72a2162" (TxIx 0)
, lovelaceToTxOutValue $ Lovelace 90000000000000
)

genesisFund :: Fund
genesisFund
= Fund $ InAnyCardanoEra BabbageEra fundInEra
where
fundInEra :: FundInEra BabbageEra
fundInEra = FundInEra {
_fundTxIn = genesisTxIn
, _fundVal = genesisValue
, _fundSigningKey = Just signingKey
, _fundValidity = Confirmed
, _fundVariant = PlainOldFund
}

type Generator = State [Fund]

generateTx ::
ProtocolParameters
-> Generator (Either String (Tx BabbageEra))
generateTx protocolParameters
= sourceToStoreTransaction
generator
consumeInputFunds
computeOutputValues
computeUTxOs
addNewOutputFunds
where
-- In the simplest form of the tx-generator
-- fees, metadata etc.. are all hardcoded.

networkId :: NetworkId
networkId = Mainnet

-- hardcoded fees
fee :: Lovelace
fee = 100000

babbageFee :: TxFee BabbageEra
babbageFee = TxFeeExplicit TxFeesExplicitInBabbageEra fee

metadata :: TxMetadataInEra BabbageEra
metadata = TxMetadataNone

generator :: TxGenerator BabbageEra
generator = genTx protocolParameters collateralFunds babbageFee metadata witness
where
-- collateralFunds are needed for Plutus transactions
collateralFunds :: (TxInsCollateral BabbageEra, [Fund])
collateralFunds = (TxInsCollateralNone, [])

witness :: Witness WitCtxTxIn BabbageEra
witness = KeyWitness KeyWitnessForSpending

-- Create a transaction that uses all the available funds.
consumeInputFunds :: Generator (Either String [Fund])
consumeInputFunds = do
funds <- get
put []
return $ Right funds

addNewOutputFunds :: [Fund] -> Generator ()
addNewOutputFunds = put

computeOutputValues :: [Lovelace] -> [Lovelace]
computeOutputValues = inputsToOutputsWithFee fee numOfOutputs
where numOfOutputs = 2

computeUTxOs = mkUTxOVariant PlainOldFund networkId signingKey Confirmed
1 change: 1 addition & 0 deletions bench/tx-generator/tx-generator.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ library
Cardano.Benchmarking.Wallet
Cardano.Benchmarking.ListBufferedSelector
Cardano.Benchmarking.PlutusExample
Cardano.TxGenerator.PureExample

other-modules: Paths_tx_generator

Expand Down

0 comments on commit 86c3af2

Please sign in to comment.