Skip to content

Commit c3bffcf

Browse files
committed
tx-generator: Add named wallets
tx-generator script can now use multiple named wallets to control which UTxO is spend in which benchmarking phase. Before all UTxOs were managed in a single wallet.
1 parent 4ec3029 commit c3bffcf

File tree

8 files changed

+185
-112
lines changed

8 files changed

+185
-112
lines changed

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

Lines changed: 81 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,39 @@ import Cardano.Api
1818
import Cardano.Benchmarking.Types
1919
import Cardano.Benchmarking.NixOptions
2020
import Cardano.Benchmarking.Script.Setters
21-
import Cardano.Benchmarking.Script.Store (Name(..))
21+
import Cardano.Benchmarking.Script.Store (Name(..), WalletName)
2222
import Cardano.Benchmarking.Script.Types
2323

2424
data CompileError where
2525
SomeCompilerError :: CompileError
2626
deriving (Show)
27-
type Compiler a = RWST NixServiceOptions (DList Action) () (Except CompileError) a
27+
type Compiler a = RWST NixServiceOptions (DList Action) Int (Except CompileError) a
28+
29+
type SrcWallet = WalletName
30+
type DstWallet = WalletName
2831

2932
compileOptions :: NixServiceOptions -> Either CompileError [Action]
30-
compileOptions = runCompiler compileToScript
33+
compileOptions opts = runCompiler opts compileToScript
3134

32-
runCompiler :: Compiler () -> NixServiceOptions -> Either CompileError [Action]
33-
runCompiler c o = case runExcept $ runRWST c o () of
35+
runCompiler ::NixServiceOptions -> Compiler () -> Either CompileError [Action]
36+
runCompiler o c = case runExcept $ runRWST c o 0 of
3437
Left err -> Left err
3538
Right ((), _ , l) -> Right $ DL.toList l
3639

37-
testCompiler :: Compiler a -> NixServiceOptions -> Either CompileError (a, (), [Action])
38-
testCompiler c o = case runExcept $ runRWST c o () of
40+
testCompiler :: NixServiceOptions -> Compiler a -> Either CompileError (a, Int, [Action])
41+
testCompiler o c = case runExcept $ runRWST c o 0 of
3942
Left err -> Left err
4043
Right (a, s , l) -> Right (a, s, DL.toList l)
4144

4245
compileToScript :: Compiler ()
4346
compileToScript = do
4447
initConstants
4548
emit . StartProtocol =<< askNixOption _nix_nodeConfigFile
46-
importGenesisFunds
47-
initCollaterals
48-
splittingPhase
49-
benchmarkingPhase
49+
genesisWallet <- newWallet "genesis_wallet"
50+
importGenesisFunds genesisWallet
51+
splitWallet <- splittingPhase genesisWallet
52+
addCollaterals genesisWallet splitWallet
53+
benchmarkingPhase splitWallet
5054

5155
initConstants :: Compiler ()
5256
initConstants = do
@@ -67,61 +71,78 @@ initConstants = do
6771
setN :: Tag v -> (NixServiceOptions -> v) -> Compiler ()
6872
setN key s = askNixOption s >>= setConst key
6973

70-
importGenesisFunds :: Compiler ()
71-
importGenesisFunds = do
74+
importGenesisFunds :: DstWallet -> Compiler ()
75+
importGenesisFunds wallet = do
7276
cmd1 (ReadSigningKey $ KeyName "pass-partout") _nix_sigKey
73-
emit $ ImportGenesisFund LocalSocket (KeyName "pass-partout") (KeyName "pass-partout")
77+
emit $ ImportGenesisFund wallet LocalSocket (KeyName "pass-partout") (KeyName "pass-partout")
7478
delay
7579

76-
initCollaterals :: Compiler ()
77-
initCollaterals = do
80+
addCollaterals :: SrcWallet -> DstWallet -> Compiler ()
81+
addCollaterals src dest = do
7882
isAnyPlutusMode >>= \case
7983
False -> return ()
8084
True -> do
8185
tx_fee <- askNixOption _nix_tx_fee
8286
safeCollateral <- _safeCollateral <$> evilFeeMagic
83-
emit $ CreateChange LocalSocket (PayToAddr $ KeyName "pass-partout") (safeCollateral + tx_fee) 1
84-
emit $ CreateChange LocalSocket (PayToCollateral $ KeyName "pass-partout") safeCollateral 1
87+
emit $ CreateChange src src LocalSocket (PayToAddr $ KeyName "pass-partout") (safeCollateral + tx_fee) 1
88+
emit $ CreateChange src dest LocalSocket (PayToCollateral $ KeyName "pass-partout") safeCollateral 1
8589

86-
splittingPhase :: Compiler ()
87-
splittingPhase = do
90+
splittingPhase :: SrcWallet -> Compiler DstWallet
91+
splittingPhase srcWallet = do
8892
(NumberOfTxs tx_count) <- askNixOption _nix_tx_count
8993
(NumberOfInputsPerTx inputs_per_tx) <- askNixOption _nix_inputs_per_tx
94+
tx_fee <- askNixOption _nix_tx_fee
9095
minValuePerInput <- _minValuePerInput <$> evilFeeMagic
96+
splitSteps <- splitSequenceWalletNames srcWallet srcWallet $ unfoldSplitSequence tx_fee minValuePerInput (tx_count * inputs_per_tx)
97+
forM_ (init splitSteps) createChange
9198
plutus <- isAnyPlutusMode
92-
if plutus then createChangeRecursivePlutus minValuePerInput (tx_count * inputs_per_tx)
93-
else createChangeRecursive minValuePerInput (tx_count * inputs_per_tx)
99+
(if plutus then createChangePlutus else createChange) $ last splitSteps
94100
where
95-
createChangeRecursive :: Lovelace -> Int -> Compiler ()
96-
createChangeRecursive value count = do
97-
when (count > 30) $ do
98-
tx_fee <- askNixOption _nix_tx_fee
99-
createChangeRecursive (value * 30 + tx_fee) (count `div` 30 + 1)
100-
createChange value count
101-
102-
createChangeRecursivePlutus :: Lovelace -> Int -> Compiler ()
103-
createChangeRecursivePlutus value count = do
104-
when (count > 30) $ do
105-
tx_fee <- askNixOption _nix_tx_fee
106-
createChangeRecursive (value * 30 + tx_fee) (count `div` 30 + 1)
107-
createChangePlutus value count
108-
109-
createChange :: Lovelace -> Int -> Compiler ()
110-
createChange value count = do
111-
emit $ CreateChange LocalSocket (PayToAddr $ KeyName "pass-partout") value count
101+
createChange :: SplitStep -> Compiler DstWallet
102+
createChange (src, dst, value, count) = do
103+
emit $ CreateChange src dst LocalSocket (PayToAddr $ KeyName "pass-partout") value count
112104
delay
105+
return dst
113106

114-
createChangePlutus :: Lovelace -> Int -> Compiler ()
115-
createChangePlutus value count = do
107+
createChangePlutus :: SplitStep -> Compiler DstWallet
108+
createChangePlutus (src, dst, value, count) = do
116109
autoMode <- isPlutusAutoMode
117110
plutusTarget <- if autoMode
118111
then PayToScript <$> askNixOption _nix_plutusLoopScript <*> pure (ScriptDataNumber 0)
119112
else PayToScript <$> askNixOption _nix_plutusScript <*> (ScriptDataNumber <$> askNixOption _nix_plutusData)
120-
emit $ CreateChange LocalSocket plutusTarget value count
113+
emit $ CreateChange src dst LocalSocket plutusTarget value count
121114
delay
122-
123-
benchmarkingPhase :: Compiler ()
124-
benchmarkingPhase = do
115+
return dst
116+
117+
-- Generate src and dst wallet names for a splitSequence.
118+
-- testCompiler (error "opts") $ splitSequenceWalletNames (WalletName "w1") (WalletName "w2") (unfoldSplitSequence 1 1000 10000)
119+
type SplitStep = (SrcWallet, DstWallet, Lovelace, Int)
120+
121+
splitSequenceWalletNames :: SrcWallet -> DstWallet -> [(Lovelace, Int)] -> Compiler [ SplitStep ]
122+
splitSequenceWalletNames _src _dst [] = return []
123+
splitSequenceWalletNames src dst [ (val,count) ] = return [( src, dst, val, count)]
124+
splitSequenceWalletNames src dst ((val, count):rest) = do
125+
nextDst <- newWallet "change_wallet"
126+
l <- splitSequenceWalletNames dst nextDst rest
127+
return $ [( src, dst, val, count)] ++ l
128+
129+
-- Return a list of splitSteps.
130+
unfoldSplitSequence :: Lovelace -> Lovelace -> Int -> [(Lovelace, Int)]
131+
unfoldSplitSequence fee value count
132+
= if count < maxOutputs
133+
then [
134+
-- Add an extra transaction that just contains the desired output and possible fees.
135+
(value * fromIntegral count + fee, 1)
136+
, (value, count )
137+
]
138+
else unfoldSplitSequence fee (value * fromIntegral maxOutputs + fee) (count `div` maxOutputs + 1) ++ [ (value, count) ]
139+
where
140+
-- maximal number of outputs in a TX.
141+
-- todo: this must be in sync with Scipt/Core.hs
142+
maxOutputs = 30
143+
144+
benchmarkingPhase :: WalletName -> Compiler ()
145+
benchmarkingPhase wallet = do
125146
debugMode <- askNixOption _nix_debugMode
126147
plutusMode <- askNixOption _nix_plutusMode
127148
plutusAutoMode <- askNixOption _nix_plutusAutoMode
@@ -140,7 +161,7 @@ benchmarkingPhase = do
140161
<*> (ScriptDataNumber <$> askNixOption _nix_plutusData)
141162
<*> (ScriptDataNumber <$> askNixOption _nix_plutusRedeemer)
142163
(False,False) -> return SpendOutput
143-
emit $ RunBenchmark target spendMode (ThreadName "tx-submit-benchmark") tx_count tps
164+
emit $ RunBenchmark wallet target spendMode (ThreadName "tx-submit-benchmark") tx_count tps
144165
unless debugMode $ do
145166
emit $ WaitBenchmark $ ThreadName "tx-submit-benchmark"
146167

@@ -191,3 +212,17 @@ isPlutusAutoMode = askNixOption _nix_plutusAutoMode
191212

192213
isAnyPlutusMode :: Compiler Bool
193214
isAnyPlutusMode = liftA2 (||) isPlutusMode isPlutusAutoMode
215+
216+
newIdentifier :: String -> Compiler String
217+
newIdentifier prefix = do
218+
n <- get
219+
put $ succ n
220+
return $ prefix ++ "_" ++ show n
221+
222+
newWallet :: String -> Compiler WalletName
223+
newWallet n = do
224+
name <- WalletName <$> newIdentifier n
225+
emit $ InitWallet name
226+
return name
227+
228+

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Cardano.Node.Configuration.Logging (shutdownLoggingLayer)
1919
import Cardano.Benchmarking.Tracer (createDebugTracers)
2020
import Cardano.Benchmarking.Script.Action
2121
import Cardano.Benchmarking.Script.Aeson (parseScriptFileAeson)
22-
import Cardano.Benchmarking.Script.Core (initGlobalWallet, setProtocolParameters)
22+
import Cardano.Benchmarking.Script.Core (setProtocolParameters)
2323
import Cardano.Benchmarking.Script.Env
2424
import Cardano.Benchmarking.Script.Store
2525
import Cardano.Benchmarking.Script.Types
@@ -40,7 +40,6 @@ runScript script iom = runActionM execScript iom >>= \case
4040
cleanup s a = void $ runActionMEnv s a iom
4141
execScript = do
4242
set BenchTracers createDebugTracers
43-
initGlobalWallet
4443
setProtocolParameters QueryLocalNode
4544
forM_ script action
4645

bench/tx-generator/src/Cardano/Benchmarking/Script/Action.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ import Cardano.Benchmarking.Script.Types
1212
action :: Action -> ActionM ()
1313
action a = case a of
1414
Set (key :=> (Identity val)) -> set (User key) val
15+
InitWallet name -> initWallet name
1516
SetProtocolParameters p -> setProtocolParameters p
1617
StartProtocol filePath -> startProtocol filePath
1718
ReadSigningKey name filePath -> readSigningKey name filePath
1819
DefineSigningKey name descr -> defineSigningKey name descr
19-
AddFund txIn lovelace keyName -> addFund txIn lovelace keyName
20+
AddFund wallet txIn lovelace keyName -> addFund wallet txIn lovelace keyName
2021
Delay t -> delay t
21-
ImportGenesisFund submitMode genesisKey fundKey -> importGenesisFund submitMode genesisKey fundKey
22-
CreateChange payMode submitMode value count -> createChange payMode submitMode value count
23-
RunBenchmark submitMode spendMode thread count tps -> runBenchmark submitMode spendMode thread count tps
22+
ImportGenesisFund wallet submitMode genesisKey fundKey -> importGenesisFund wallet submitMode genesisKey fundKey
23+
CreateChange sourceWallet dstWallet payMode submitMode value count -> createChange sourceWallet dstWallet payMode submitMode value count
24+
RunBenchmark sourceWallet submitMode spendMode thread count tps -> runBenchmark sourceWallet submitMode spendMode thread count tps
2425
WaitBenchmark thread -> waitBenchmark thread
2526
CancelBenchmark thread -> cancelBenchmark thread
2627
WaitForEra era -> waitForEra era

bench/tx-generator/src/Cardano/Benchmarking/Script/Aeson.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,12 @@ readProtocolParametersFile = parseJSONFile fromJSON
143143

144144
instance ToJSON KeyName where toJSON (KeyName a) = toJSON a
145145
instance ToJSON ThreadName where toJSON (ThreadName a) = toJSON a
146+
instance ToJSON WalletName where toJSON (WalletName a) = toJSON a
146147
instance ToJSON SigningKeyFile where toJSON (SigningKeyFile a) = toJSON a
147148

148149
instance FromJSON KeyName where parseJSON a = KeyName <$> parseJSON a
149150
instance FromJSON ThreadName where parseJSON a = ThreadName <$> parseJSON a
151+
instance FromJSON WalletName where parseJSON a = WalletName <$> parseJSON a
150152
instance FromJSON SigningKeyFile where parseJSON a = SigningKeyFile <$> parseJSON a
151153

152154
instance ToJSON NetworkId where

0 commit comments

Comments
 (0)