Skip to content

Commit 32e0470

Browse files
iohk-bors[bot]mgmeierNadiaYvette
authored
Merge #4460
4460: tx-generator: reusable API and library r=mgmeier a=mgmeier Co-authored-by: Michael Karg <[email protected]> Co-authored-by: Nadia Yvette Chambers <[email protected]>
2 parents 57161f7 + c2e8693 commit 32e0470

33 files changed

+1347
-821
lines changed

bench/tx-generator/src/Cardano/Benchmarking/Command.hs

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ where
1313
import Prelude
1414
import System.Exit
1515

16+
import Data.Aeson (fromJSON)
1617
import Data.ByteString.Lazy as BSL
1718
import Data.Text.IO as T
1819
import Options.Applicative as Opt
1920

2021
import Ouroboros.Network.NodeToClient (withIOManager)
2122

2223
import Cardano.Benchmarking.Compiler (compileOptions)
23-
import Cardano.Benchmarking.NixOptions (NixServiceOptions, _nix_nodeConfigFile, _nix_cardanoTracerSocket,
24-
parseNixServiceOptions, setNodeConfigFile)
2524
import Cardano.Benchmarking.Script (parseScriptFileAeson, runScript)
26-
import Cardano.Benchmarking.Script.Aeson (prettyPrint)
25+
import Cardano.Benchmarking.Script.Aeson (parseJSONFile, prettyPrint)
2726
import Cardano.Benchmarking.Script.Selftest (runSelftest)
2827
import Cardano.Benchmarking.Version as Version
28+
import Cardano.TxGenerator.Setup.NixService
29+
2930

3031
data Command
3132
= Json FilePath
@@ -44,13 +45,13 @@ runCommand = withIOManager $ \iocp -> do
4445
script <- parseScriptFileAeson file
4546
runScript script iocp >>= handleError
4647
JsonHL file nodeConfigOverwrite cardanoTracerOverwrite -> do
47-
opts <- parseNixServiceOptions file
48+
opts <- parseJSONFile fromJSON file
4849
finalOpts <- mangleTracerConfig cardanoTracerOverwrite <$> mangleNodeConfig nodeConfigOverwrite opts
4950
case compileOptions finalOpts of
5051
Right script -> runScript script iocp >>= handleError
5152
err -> handleError err
5253
Compile file -> do
53-
o <- parseNixServiceOptions file
54+
o <- parseJSONFile fromJSON file
5455
case compileOptions o of
5556
Right script -> BSL.putStr $ prettyPrint script
5657
err -> handleError err
@@ -63,7 +64,7 @@ runCommand = withIOManager $ \iocp -> do
6364
Left err -> die $ show err
6465

6566
mangleNodeConfig :: Maybe FilePath -> NixServiceOptions -> IO NixServiceOptions
66-
mangleNodeConfig fp opts = case (_nix_nodeConfigFile opts, fp) of
67+
mangleNodeConfig fp opts = case (getNodeConfigFile opts, fp) of
6768
(_ , Just newFilePath) -> return $ setNodeConfigFile opts newFilePath
6869
(Just _ , Nothing) -> return opts
6970
(Nothing, Nothing) -> die "No node-configFile set"
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
11
{-# LANGUAGE GADTs #-}
22
{-# LANGUAGE LambdaCase #-}
3+
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
34
module Cardano.Benchmarking.Compiler
45
where
56

67
import Prelude
78

89
import Control.Applicative (liftA2)
910
import Control.Monad
11+
import Control.Monad.Trans.Class (lift)
1012
import Control.Monad.Trans.Except
1113
import Control.Monad.Trans.RWS.CPS
12-
import Data.ByteString.Base16 as Base16
1314
import Data.ByteString as BS (ByteString)
14-
import Data.Dependent.Sum ( (==>) )
1515
import Data.DList (DList)
1616
import qualified Data.DList as DL
1717
import Data.Text (Text)
1818
import qualified Data.Text as Text
1919

2020
import Cardano.Api
21-
22-
import Cardano.Benchmarking.NixOptions
23-
import Cardano.Benchmarking.Script.Setters
24-
import Cardano.Benchmarking.Script.Store (KeyName, Name(..), WalletName)
2521
import Cardano.Benchmarking.Script.Types
22+
import Cardano.TxGenerator.Setup.NixService
23+
import Cardano.TxGenerator.Setup.SigningKey
24+
import Cardano.TxGenerator.Types (TxGenTxParams (..))
2625

2726
data CompileError where
28-
SomeCompilerError :: CompileError
27+
SomeCompilerError :: String -> CompileError
2928
deriving (Show)
3029
type Compiler a = RWST NixServiceOptions (DList Action) Int (Except CompileError) a
3130

31+
throwCompileError :: CompileError -> Compiler a
32+
throwCompileError = lift . throwE
33+
3234
maxOutputsPerTx :: Int
3335
maxOutputsPerTx = 30
3436

35-
type SrcWallet = WalletName
36-
type DstWallet = WalletName
37+
type SrcWallet = String
38+
type DstWallet = String
3739

3840
compileOptions :: NixServiceOptions -> Either CompileError [Action]
3941
compileOptions opts = runCompiler opts compileToScript
@@ -51,84 +53,82 @@ testCompiler o c = case runExcept $ runRWST c o 0 of
5153
compileToScript :: Compiler ()
5254
compileToScript = do
5355
initConstants
54-
StartProtocol <$> askNixOption getNodeConfigFile <*> askNixOption _nix_cardanoTracerSocket >>= emit
56+
nc <- askNixOption getNodeConfigFile >>= maybe
57+
(throwCompileError $ SomeCompilerError "nodeConfigFile not set in Nix options")
58+
pure
59+
tc <- askNixOption _nix_cardanoTracerSocket
60+
emit $ StartProtocol nc tc
5561
genesisWallet <- importGenesisFunds
5662
collateralWallet <- addCollaterals genesisWallet
5763
splitWallet <- splittingPhase genesisWallet
5864
void $ benchmarkingPhase splitWallet collateralWallet
5965

6066
initConstants :: Compiler ()
6167
initConstants = do
62-
setN TLocalSocket _nix_localNodeSocketPath
63-
setConst TTTL 1000000
68+
p <- askNixOption _nix_localNodeSocketPath
69+
emit $ SetSocketPath p
6470
emit $ DefineSigningKey keyNameTxGenFunds keyTxGenFunds
6571
emit $ DefineSigningKey keyNameCollaterals keyCollaterals
6672
emit $ DefineSigningKey keyNameSplitPhase keySplitPhase
6773
emit $ DefineSigningKey keyNameBenchmarkInputs keyBenchmarkInputs
6874
emit $ DefineSigningKey keyNameBenchmarkDone keyBenchmarkDone
69-
where
70-
setConst :: Tag v -> v -> Compiler ()
71-
setConst key val = emit $ Set $ key ==> val
7275

73-
setN :: Tag v -> (NixServiceOptions -> v) -> Compiler ()
74-
setN key s = askNixOption s >>= setConst key
75-
76-
importGenesisFunds :: Compiler WalletName
76+
importGenesisFunds :: Compiler String
7777
importGenesisFunds = do
7878
logMsg "Importing Genesis Fund."
7979
wallet <- newWallet "genesis_wallet"
8080
era <- askNixOption _nix_era
81-
fee <- askNixOption _nix_tx_fee
81+
txParams <- askNixOption txGenTxParams
8282
cmd1 (ReadSigningKey keyNameGenesisInputFund) _nix_sigKey
83-
emit $ Submit era LocalSocket $ SecureGenesis fee wallet keyNameGenesisInputFund keyNameTxGenFunds
83+
emit $ Submit era LocalSocket txParams $ SecureGenesis wallet keyNameGenesisInputFund keyNameTxGenFunds
8484
delay
8585
logMsg "Importing Genesis Fund. Done."
8686
return wallet
8787

88-
addCollaterals :: SrcWallet -> Compiler (Maybe WalletName)
88+
addCollaterals :: SrcWallet -> Compiler (Maybe String)
8989
addCollaterals src = do
9090
era <- askNixOption _nix_era
91+
txParams <- askNixOption txGenTxParams
9192
isAnyPlutusMode >>= \case
9293
False -> return Nothing
9394
True -> do
9495
logMsg "Create collaterals."
9596
safeCollateral <- _safeCollateral <$> evilFeeMagic
9697
collateralWallet <- newWallet "collateral_wallet"
97-
fee <- askNixOption _nix_tx_fee
98-
let generator = Split fee src
98+
let generator = Split src
9999
(PayToAddr keyNameCollaterals collateralWallet)
100100
(PayToAddr keyNameTxGenFunds src)
101101
[ safeCollateral ]
102-
emit $ Submit era LocalSocket generator
102+
emit $ Submit era LocalSocket txParams generator
103103
logMsg "Create collaterals. Done."
104104
return $ Just collateralWallet
105105

106106
splittingPhase :: SrcWallet -> Compiler DstWallet
107107
splittingPhase srcWallet = do
108108
tx_count <- askNixOption _nix_tx_count
109109
inputs_per_tx <- askNixOption _nix_inputs_per_tx
110-
tx_fee <- askNixOption _nix_tx_fee
111-
era <- askNixOption _nix_era
110+
era <- askNixOption _nix_era
111+
txParams <- askNixOption txGenTxParams
112112
minValuePerInput <- _minValuePerInput <$> evilFeeMagic
113113
finalDest <- newWallet "final_split_wallet"
114-
splitSteps <- splitSequenceWalletNames srcWallet finalDest $ unfoldSplitSequence tx_fee minValuePerInput (tx_count * inputs_per_tx)
114+
splitSteps <- splitSequenceWalletNames srcWallet finalDest $
115+
unfoldSplitSequence (txParamFee txParams) minValuePerInput (tx_count * inputs_per_tx)
115116
isPlutus <- isAnyPlutusMode
116-
forM_ (init splitSteps) $ createChange False False era
117-
createChange True isPlutus era $ last splitSteps
117+
forM_ (init splitSteps) $ createChange txParams False False era
118+
createChange txParams True isPlutus era $ last splitSteps
118119
return finalDest
119120
where
120-
createChange :: Bool -> Bool -> AnyCardanoEra -> (SrcWallet, DstWallet, Split) -> Compiler ()
121-
createChange isLastStep isPlutus era (src, dst, split) = do
121+
createChange :: TxGenTxParams -> Bool -> Bool -> AnyCardanoEra -> (SrcWallet, DstWallet, Split) -> Compiler ()
122+
createChange txParams isLastStep isPlutus era (src, dst, split) = do
122123
logMsg $ Text.pack $ "Splitting step: " ++ show split
123-
tx_fee <- askNixOption _nix_tx_fee
124124
let valuePayMode = PayToAddr (if isLastStep then keyNameSplitPhase else keyNameBenchmarkInputs) dst
125125
payMode <- if isPlutus then plutusPayMode dst else return valuePayMode
126126
let generator = case split of
127-
SplitWithChange lovelace count -> Split tx_fee src payMode (PayToAddr keyNameTxGenFunds src) $ replicate count lovelace
128-
FullSplits txCount -> Take txCount $ Cycle $ SplitN tx_fee src payMode maxOutputsPerTx
129-
emit $ Submit era LocalSocket generator
127+
SplitWithChange lovelace count -> Split src payMode (PayToAddr keyNameTxGenFunds src) $ replicate count lovelace
128+
FullSplits txCount -> Take txCount $ Cycle $ SplitN src payMode maxOutputsPerTx
129+
emit $ Submit era LocalSocket txParams generator
130130
delay
131-
logMsg "Splitting step: Done"
131+
logMsg "Splitting step: Done"
132132

133133
plutusPayMode :: DstWallet -> Compiler PayMode
134134
plutusPayMode dst = do
@@ -175,44 +175,43 @@ unfoldSplitSequence fee value outputs
175175
(x, 0) -> x
176176
(x, _rest) -> x+1
177177

178-
benchmarkingPhase :: WalletName -> Maybe WalletName -> Compiler WalletName
178+
benchmarkingPhase :: String -> Maybe String -> Compiler String
179179
benchmarkingPhase wallet collateralWallet = do
180180
debugMode <- askNixOption _nix_debugMode
181181
targetNodes <- askNixOption _nix_targetNodes
182182
tps <- askNixOption _nix_tps
183183
era <- askNixOption _nix_era
184184
txCount <- askNixOption _nix_tx_count
185-
fee <- askNixOption _nix_tx_fee
186185
inputs <- askNixOption _nix_inputs_per_tx
187186
outputs <- askNixOption _nix_outputs_per_tx
188-
metadataSize <- askNixOption _nix_add_tx_size
187+
txParams <- askNixOption txGenTxParams
189188
doneWallet <- newWallet "done_wallet"
190189
let
191190
payMode = PayToAddr keyNameBenchmarkDone doneWallet
192191
submitMode = if debugMode
193192
then LocalSocket
194-
else Benchmark targetNodes (ThreadName "tx-submit-benchmark") tps txCount
195-
generator = Take txCount $ Cycle $ NtoM fee wallet payMode inputs outputs (Just metadataSize) collateralWallet
196-
emit $ Submit era submitMode generator
193+
else Benchmark targetNodes "tx-submit-benchmark" tps txCount
194+
generator = Take txCount $ Cycle $ NtoM wallet payMode inputs outputs (Just $ txParamAddTxSize txParams) collateralWallet
195+
emit $ Submit era submitMode txParams generator
197196
unless debugMode $ do
198-
emit $ WaitBenchmark $ ThreadName "tx-submit-benchmark"
197+
emit $ WaitBenchmark "tx-submit-benchmark"
199198
return doneWallet
200199

201200
data Fees = Fees {
202201
_safeCollateral :: Lovelace
203202
, _minValuePerInput :: Lovelace
204203
}
205-
204+
206205
evilFeeMagic :: Compiler Fees
207206
evilFeeMagic = do
208207
(Quantity tx_fee) <- lovelaceToQuantity <$> askNixOption _nix_tx_fee
209-
plutusMode <- askNixOption _nix_plutusMode
208+
plutusMode <- askNixOption _nix_plutusMode
210209
inputs_per_tx <- askNixOption _nix_inputs_per_tx
211-
outputs_per_tx <- askNixOption _nix_outputs_per_tx
210+
outputs_per_tx <- askNixOption _nix_outputs_per_tx
212211
(Quantity min_utxo_value) <- lovelaceToQuantity <$> askNixOption _nix_min_utxo_value
213212
let
214-
scriptFees = 5000000;
215-
collateralPercentage = 200;
213+
scriptFees = 5000000; -- FIXME: should be taken from ProtocolParameters
214+
collateralPercentage = 200; -- FIXME: should be taken from ProtocolParameters
216215

217216
totalFee = if plutusMode
218217
then tx_fee + scriptFees * fromIntegral inputs_per_tx
@@ -233,7 +232,7 @@ logMsg = emit . LogMsg
233232

234233
cmd1 :: (v -> Action) -> (NixServiceOptions -> v) -> Compiler ()
235234
cmd1 cmd arg = emit . cmd =<< askNixOption arg
236-
235+
237236
askNixOption :: (NixServiceOptions -> v) -> Compiler v
238237
askNixOption = asks
239238

@@ -255,60 +254,55 @@ newIdentifier prefix = do
255254
put $ succ n
256255
return $ prefix ++ "_" ++ show n
257256

258-
newWallet :: String -> Compiler WalletName
257+
newWallet :: String -> Compiler String
259258
newWallet n = do
260-
name <- WalletName <$> newIdentifier n
259+
name <- newIdentifier n
261260
emit $ InitWallet name
262261
return name
263262

264-
parseKey :: BS.ByteString -> TextEnvelope
265-
parseKey x = case Base16.decode x of
266-
Left err -> error $ "parsing of key failed : " ++ show err
267-
Right addr -> TextEnvelope
268-
{ teType = TextEnvelopeType "PaymentSigningKeyShelley_ed25519"
269-
, teDescription = "Payment Signing Key"
270-
, teRawCBOR = addr
271-
}
272-
263+
-- we assume the hardcoded base16 keys to successfully evaluate to a SigningKey PaymentKey
264+
parseKey :: BS.ByteString -> SigningKey PaymentKey
265+
parseKey k
266+
= let ~(Right k') = parseSigningKeyBase16 k in k'
273267

274-
keyNameGenesisInputFund :: KeyName
275-
keyNameGenesisInputFund = KeyName "GenesisInputFund"
268+
keyNameGenesisInputFund :: String
269+
keyNameGenesisInputFund = "GenesisInputFund"
276270

277-
keyNameTxGenFunds :: KeyName
278-
keyNameTxGenFunds = KeyName "TxGenFunds"
271+
keyNameTxGenFunds :: String
272+
keyNameTxGenFunds = "TxGenFunds"
279273

280274
{-|
281275
The key that is used for the very first transaction, i.e. the secure Genesis transaction.
282276
addr_test1vzd3muund27y5nw83vymqj3a83pcuzkkejej6s75e5lfjcc85nc3p is the actual address (in Testnet 42).
283277
It is also used as change addresse in the first splitting-step.
284278
-}
285-
keyTxGenFunds :: TextEnvelope
279+
keyTxGenFunds :: SigningKey PaymentKey
286280
keyTxGenFunds = parseKey "5820617f846fc8b0e753bd51790de5f5a916de500175c6f5a0e27dde9da7879e1d35"
287281

288-
keyNameSplitPhase :: KeyName
289-
keyNameSplitPhase = KeyName "SplitPhase"
282+
keyNameSplitPhase :: String
283+
keyNameSplitPhase = "SplitPhase"
290284

291285
{-|
292286
UTxOs that are generated in intermediate splitting steps use:
293287
addr_test1vz45dtkyzk6s3245qw8hmaddaatcx8td3pvmntl8ty7q99c22eahm
294288
-}
295289

296-
keySplitPhase :: TextEnvelope
290+
keySplitPhase :: SigningKey PaymentKey
297291
keySplitPhase = parseKey "5820cf0083c2a5d4c90ab255bc8e68f407d52eebd9408de60a0b9e4c468f9714f076"
298292

299293
{-|
300294
UTxOs of the final splitting steps, i.e. the inputs of the benchmarking phase, use:
301295
addr_test1vzj7zv9msmdasvy5nc9jhnn2gqvrvu33v5rlg332zdfrkugklxkau
302296
(Plutus script addresses are ofc different.)
303297
-}
304-
keyNameBenchmarkInputs :: KeyName
305-
keyNameBenchmarkInputs = KeyName "BenchmarkInputs"
298+
keyNameBenchmarkInputs :: String
299+
keyNameBenchmarkInputs = "BenchmarkInputs"
306300

307-
keyBenchmarkInputs :: TextEnvelope
301+
keyBenchmarkInputs :: SigningKey PaymentKey
308302
keyBenchmarkInputs = parseKey "58205b7f272602661d4ad3d9a4081f25fdcdcdf64fdc4892107de50e50937b77ea42"
309303

310-
keyNameBenchmarkDone :: KeyName
311-
keyNameBenchmarkDone = KeyName "BenchmarkingDone"
304+
keyNameBenchmarkDone :: String
305+
keyNameBenchmarkDone = "BenchmarkingDone"
312306

313307
{-|
314308
The output of the actual benchmarking transactions use:
@@ -317,15 +311,15 @@ Query the progress of the benchmarking phase:
317311
`cardano-node query utxo --testnet-magic 42 --address addr_test1vz4qz2ayucp7xvnthrx93uhha7e04gvxttpnuq4e6mx2n5gzfw23z`
318312
-}
319313

320-
keyBenchmarkDone :: TextEnvelope
314+
keyBenchmarkDone :: SigningKey PaymentKey
321315
keyBenchmarkDone = parseKey "582016ca4f13fa17557e56a7d0dd3397d747db8e1e22fdb5b9df638abdb680650d50"
322316

323-
keyNameCollaterals :: KeyName
324-
keyNameCollaterals = KeyName "Collaterals"
317+
keyNameCollaterals :: String
318+
keyNameCollaterals = "Collaterals"
325319

326320
{-|
327321
Collateral inputs for Plutus transactions:
328322
addr_test1vpckd9muw3l4f8ne4uzumy28p0k84rvx48q46kssjkta5ng4v6sfs
329323
-}
330-
keyCollaterals :: TextEnvelope
324+
keyCollaterals :: SigningKey PaymentKey
331325
keyCollaterals = parseKey "58204babdb63537ccdac393ea23d042af3b7c3587d7dc88ed3b66c959f198ad358fa"

0 commit comments

Comments
 (0)