Skip to content

Commit edd3197

Browse files
authored
Merge pull request #6173 from IntersectMBO/bench-master
bench: new script calibration tool + much maintenance
2 parents d0dcd9b + fd8e564 commit edd3197

File tree

30 files changed

+20357
-7927
lines changed

30 files changed

+20357
-7927
lines changed

CONTRIBUTING.rst

+29-30
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ On how to set up Nix for ``cardano-node`` development, please see `Building Card
88

99

1010
Roles and Responsibilities
11-
====
11+
==========================
1212

1313
We maintain a [CODEOWNERS file][CODEOWNERS] which provides information who
1414
should review a contributing PR. Note that you might need to get approvals
@@ -18,43 +18,43 @@ from all code owners (even though GitHub doesn't give a way to enforce it).
1818

1919

2020
Supplementary tooling
21-
====
21+
=====================
2222

2323
GHCID
24-
----
24+
-----
2525

2626
run *ghcid* with: ``ghcid -c "cabal repl exe:cardano-node --reorder-goals"``
2727

2828
Testing
29-
====
29+
=======
3030

3131
``cardano-node`` is essentially a container which implements several components such networking, consensus, and storage. These components have individual test coverage. The node goes through integration and release testing by Devops/QA while automated CLI tests are ongoing alongside development.
3232

3333
Developers on ``cardano-node`` can `launch their own testnets <https://github.com/input-output-hk/cardano-node-wiki/wiki/launching-a-testnet>`_ or `run the chairman tests <https://github.com/input-output-hk/cardano-node-wiki/wiki/running-chairman-tests>`_ locally.
3434

3535
Debugging
36-
====
36+
=========
3737

3838
Pretty printing CBOR encoded files
39-
----
39+
----------------------------------
4040

4141
It may be useful to print the on chain representations of blocks, delegation certificates, txs and update proposals. There are two commands that do this (for any cbor encoded file):
4242

4343
To pretty print as CBOR:
4444
``cabal exec cardano-cli -- pretty-print-cbor --filepath CBOREncodedFile``
4545

4646
Validate CBOR files
47-
----
47+
-------------------
4848

4949
You can validate Byron era blocks, delegation certificates, txs and update proposals with the ``validate-cbor`` command.
5050

5151
``cabal exec cardano-cli -- validate-cbor --byron-block 21600 --filepath CBOREncodedByronBlockFile``
5252

5353
Updating dependencies
54-
====
54+
=====================
5555

5656
... from Hackage
57-
----
57+
----------------
5858

5959
Updating package dependencies from Hackage should work like normal in a Haskell project.
6060
The most important thing to note is that we pin the ``index-state`` of the Hackage package index in ``cabal.project``.
@@ -65,14 +65,14 @@ Because of how we use Nix to manage our Haskell build, whenever you do this you
6565
You can do this by running ``nix flake lock --update-input hackageNix``.
6666

6767
... from the Cardano package repository
68-
----
68+
---------------------------------------
6969

7070
Many Cardano packages are not on Hackage and are instead in the `Cardano package repository <https://github.com/input-output-hk/cardano-haskell-packages>`__, see the README for (lots) more information.
7171
Getting new packages from there works much like getting them from Hackage.
7272
The differences are that it has an independent ``index-state``, and that there is a different Nix command you need to run afterwards: ``nix flake lock --update-input CHaP``.
7373

7474
Using unreleased versions of dependencies
75-
~~~~
75+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7676

7777
Sometimes we need to use an unreleased version of one of our dependencies, either to fix an issue in a package that is not under our control, or to experiment with a pre-release version of one of our own packages.
7878
You can use a ``source-repository-package`` stanza to pull in the unreleased version.
@@ -83,34 +83,34 @@ In that case, release a patched version to the `Cardano package repository <http
8383
See the README for instructions.
8484

8585
Releasing a version of the node
86-
====
86+
===============================
8787

8888
(There is much more to say here, this is just a small fragment)
8989

9090
... to the Cardano package repository
91-
----
91+
-------------------------------------
9292

9393
When releasing a new version of the node, it and the other packages in this repository should be released to the `Cardano package repository <https://github.com/input-output-hk/cardano-haskell-packages>`__.
9494
See the README for instructions, including a script to automate most of the process.
9595
Please note that libraries need bounds on the version of their dependencies to avoid bitrot and be effectively reusable.
9696

97-
Workbench: a local cluster playground
98-
====
97+
Workbench: running a cluster
98+
============================
9999

100100
You can quickly spin up a local cluster (on Linux and Darwin), based on any of a wide variety of configurations, and put it under a transaction generation workload -- using the ``workbench`` environment:
101101

102102
1. Optional: choose a workbench profile:
103-
- ``default`` stands for a light-state, 6-node cluster, under saturation workload, indefinite runtime
104-
- ``ci-test`` is the profile run in the node CI -- very light, just two nodes and short runtime
105-
- ``devops`` is an unloaded profile (no transaction generation) with short slots -- ``0.2`` sec.
106-
- ..and many more -- which can be either:
107-
- listed, by ``make ps``
108-
- observed at their point of definition: `nix/workbench/profiles/prof1-variants.jq <https://github.com/intersectmbo/cardano-node/tree/master/nix/workbench/profiles/prof1-variants.jq#L333-L526>`_
103+
- ``default`` stands for a light-state, 6-node cluster, under transaction saturation workload, ~30min runtime.
104+
- ``ci-test-hydra`` is the profile run in the node CI -- very light, just two nodes, Plutus transaction worklooad, =< 3min runtime.
105+
- ``devops`` is an unloaded profile (no transaction workload) with short slots -- ``0.2`` sec.
106+
- ...and many more -- which can be:
107+
- listed by name with ``make ps``
108+
- inspected with e.g. ``cabal run cardano-profile -- by-name-pretty default-coay`` (default profile with Conway era suffix)
109109
2. Optional: select mode of operation, by optionally providing a suffix:
110-
- default -- no suffix -- just enter the workbench shell, allowing you to run ``start-cluster`` at any time. Binaries will be built locally, by ``cabal``.
111-
- ``autostay`` suffix -- enter the workbench shell, start the cluster, and stay in the shell afterwards. Binaries will be built locally, by ``cabal``.
112-
- ``autonix`` suffix -- enter the workbench shell, start the cluster. All binaries will be provided by the Nix CI.
113-
- ..there are other modes, as per `lib.mk <https://github.com/intersectmbo/cardano-node/tree/master/lib.mk>`_
110+
- no suffix (default) -- just enter the workbench shell, allowing you to run ``start-cluster`` at any time. Binaries will be built locally, by ``cabal``.
111+
- ``-nix`` suffix -- same as before, but all binaries will be built by Nix or downloaded from Hydra CI cache directly.
112+
- ``-prof`` and ``-profnix`` suffixes -- same as both before, but all binaries will be built such that GHC profiling is enabled.
113+
- ...there are other modes as per `lib.mk <https://github.com/intersectmbo/cardano-node/tree/master/lib.mk#L31-L42>`_
114114
3. Enter the workbench shell for the chosen profile & mode:
115115
``make <PROFILE-NAME>`` or ``make <PROFILE-NAME>-<SUFFIX>`` (when there is a suffix).
116116
4. Optional: start cluster:
@@ -119,12 +119,12 @@ You can quickly spin up a local cluster (on Linux and Darwin), based on any of a
119119
The workbench services are available only inside the workbench shell.
120120

121121
Using Cabal
122-
----
122+
-----------
123123

124124
By default, all binaries originating in the ``cardano-node`` repository are available to ``cabal build`` and ``cabal run``, unless the workbench was entered using one of the pure ``*nix`` modes. Note that in all cases, the dependencies for the workbench are supplied through Nix and have been built/tested on CI.
125125

126126
**Dependency localisation** -or- *Cabal&Nix for painless cross-repository work*
127-
----
127+
-------------------------------------------------------------------------------
128128

129129
The Cabal workflow described above only extends to the repository-local packages. Therefore, ordinarily, to work on ``cardano-node`` dependencies in the context of the node itself, one needs to go through an expensive multi-step process -- with committing, pushing and re-pinning of the dependency changes.
130130

@@ -168,9 +168,9 @@ Without further ado (**NOTE**: *the order of steps is important!*):
168168
7. The two packages have now become **local** -- when you try ``cabal build exe:cardano-node`` now, you'll see that Cabal starts to build these dependencies you just localised. Hacking time!
169169

170170
Hoogle
171-
----
171+
------
172172

173-
The workbench shell provides ``hoogle``, with a local database for the full set of dependencies:
173+
The workbench shell provides ``hoogle``, with a local database for the full **non-local** set of package dependencies:
174174

175175
.. code-block:: console
176176
@@ -186,4 +186,3 @@ The workbench shell provides ``hoogle``, with a local database for the full set
186186
Cardano.Ledger.Shelley.Tx TxId :: SafeHash crypto EraIndependentTxBody -> TxId crypto
187187
Ouroboros.Consensus.HardFork.Combinator data family TxId tx :: Type
188188
-- plus more results not shown, pass --count=20 to see more
189-

bench/cardano-profile/app/cardano-profile.hs

+47-45
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import Prelude
66

7-
import Data.Function ((&))
7+
import Data.Bool (bool)
88
import System.Environment (lookupEnv)
99
import GHC.Stack (HasCallStack)
1010
-- Package: aeson.
@@ -79,17 +79,19 @@ data Cli =
7979
NamesNoEra
8080
| NamesCloudNoEra
8181
| Names
82-
| All
83-
| ByName PrettyPrint String
82+
| All [CliOptions]
83+
| ByName [CliOptions] String
8484
| LibMK
8585
| NodeSpecs FilePath FilePath
8686
| EpochTimeline Integer
8787
| ToJson String
8888
| FromJson String
8989

90-
data PrettyPrint =
91-
PrettyPrint
92-
| SingleLine
90+
data CliOptions =
91+
OptPrettyPrint
92+
| OptWithEra
93+
| OptWithPlayground
94+
deriving Eq
9395

9496
--------------------------------------------------------------------------------
9597

@@ -106,31 +108,19 @@ toMap maybeObj ps = Map.fromList $ map
106108
)
107109
ps
108110

109-
-- All profiles are created/defined in the Conway era.
110-
addEras :: Map.Map String Types.Profile -> Map.Map String Types.Profile
111-
addEras = foldMap
112-
(\profile -> Map.fromList $
113-
let
114-
-- TODO: Profiles properties other than the "name" and "era" of
115-
-- type string are the only thing that change ??? Remove the
116-
-- concept of eras from the profile definitions and make it a
117-
-- workbench-level feature (???).
118-
addEra p era suffix =
119-
let name = Types.name p
120-
newName = name ++ "-" ++ suffix
121-
in (newName, p {Types.name = newName, Types.era = era})
122-
in
123-
[ addEra profile Types.Allegra "alra"
124-
, addEra profile Types.Shelley "shey"
125-
, addEra profile Types.Mary "mary"
126-
, addEra profile Types.Alonzo "alzo"
127-
, addEra profile Types.Babbage "bage"
128-
, addEra profile Types.Conway "coay"
129-
]
130-
)
131-
132111
--------------------------------------------------------------------------------
133112

113+
encoder :: Aeson.ToJSON a => [CliOptions] -> a -> BSL8.ByteString
114+
encoder opts
115+
| OptPrettyPrint `elem` opts = Aeson.encodePretty' prettyConf
116+
| otherwise = Aeson.encode
117+
where
118+
prettyConf = defConfig
119+
{ confCompare = compare
120+
, confTrailingNewline = True
121+
, confIndent = Spaces 2
122+
}
123+
134124
main :: IO ()
135125
main = do
136126
cli <- getOpts
@@ -142,24 +132,24 @@ main = do
142132
-- Print all profile names (applies overlays!!!!!).
143133
Names -> do
144134
maybeObj <- lookupOverlay -- Ignored by `NamesNoEra` and `NamesCloudNoEra`.
145-
BSL8.putStrLn $ Aeson.encode $ Map.keys $ addEras $ toMap maybeObj allProfiles
135+
BSL8.putStrLn $ Aeson.encode $ Map.keys $ Profile.addEras $ toMap maybeObj allProfiles
146136
-- Print a map with all profiles, with an optional overlay.
147-
All -> do
137+
All cliOptions -> do
138+
let
139+
targetProfiles = if OptWithPlayground `elem` cliOptions then allProfiles else performanceAndTracingProfiles
140+
enc = encoder cliOptions
141+
withEraSuffs = OptWithEra `elem` cliOptions
148142
maybeObj <- lookupOverlay -- Ignored by `NamesNoEra` and `NamesCloudNoEra`.
149-
BSL8.putStrLn $ Aeson.encode $ addEras $ toMap maybeObj allProfiles
143+
BSL8.putStrLn $ enc $ bool id Profile.addEras withEraSuffs $ toMap maybeObj targetProfiles
150144
-- Print a single profiles, with an optional overlay.
151-
(ByName prettyPrint profileName) -> do
145+
ByName cliOptions profileName -> do
152146
maybeObj <- lookupOverlay -- Ignored by `NamesNoEra` and `NamesCloudNoEra`.
153-
let profiles = addEras $ toMap maybeObj allProfiles
147+
let
148+
enc = encoder cliOptions
149+
profiles = Profile.addEras $ toMap maybeObj allProfiles
154150
case Map.lookup profileName profiles of
155-
Nothing -> error $ "No profile named \"" ++ profileName ++ "\""
156-
(Just profile) ->
157-
let
158-
prettyConf = defConfig { confCompare = compare, confTrailingNewline = True }
159-
aeson = profile & case prettyPrint of
160-
PrettyPrint -> Aeson.encodePretty' prettyConf
161-
SingleLine -> Aeson.encode
162-
in BSL8.putStrLn aeson
151+
Nothing -> error $ "No profile named \"" ++ profileName ++ "\""
152+
Just profile -> BSL8.putStrLn $ enc profile
163153
LibMK -> do
164154
mapM_ putStrLn libMk
165155
(NodeSpecs profilePath topologyPath) -> do
@@ -229,19 +219,31 @@ cliParser = OA.hsubparser $
229219
<>
230220
OA.command "all"
231221
(OA.info
232-
(pure All)
222+
(pure $ All [OptWithEra, OptWithPlayground])
233223
(OA.fullDesc <> OA.header "all" <> OA.progDesc "Create all profiles")
234224
)
225+
<>
226+
OA.command "all-noera"
227+
(OA.info
228+
(pure $ All [OptWithPlayground])
229+
(OA.fullDesc <> OA.header "all-noera" <> OA.progDesc "Create all profiles (no era suffix)")
230+
)
231+
<>
232+
OA.command "allpt-noera"
233+
(OA.info
234+
(pure $ All [OptPrettyPrint])
235+
(OA.fullDesc <> OA.header "allpt-noera" <> OA.progDesc "Create P&T profiles (no era suffix)")
236+
)
235237
<>
236238
OA.command "by-name"
237239
(OA.info
238-
(ByName SingleLine <$> OA.argument OA.str (OA.metavar "PROFILE-NAME"))
240+
(ByName [] <$> OA.argument OA.str (OA.metavar "PROFILE-NAME"))
239241
(OA.fullDesc <> OA.header "by-name" <> OA.progDesc "Create profile")
240242
)
241243
<>
242244
OA.command "by-name-pretty"
243245
(OA.info
244-
(ByName PrettyPrint <$> OA.argument OA.str (OA.metavar "PROFILE-NAME"))
246+
(ByName [OptPrettyPrint] <$> OA.argument OA.str (OA.metavar "PROFILE-NAME"))
245247
(OA.fullDesc <> OA.header "by-name-pretty" <> OA.progDesc "Create profile (pretty-printed)")
246248
)
247249
<>

bench/cardano-profile/cardano-profile.cabal

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cabal-version: 3.0
22

33
name: cardano-profile
4-
version: 8.7.0
4+
version: 8.8.0
55
synopsis: A Cardano benchmarking profile generator
66
description: A Cardano benchmarking profile generator.
77
category: Cardano,
@@ -32,7 +32,8 @@ data-files: data/all-profiles-coay.json
3232
common project-config
3333
build-depends: base >= 4.14 && < 5
3434
default-language: Haskell2010
35-
default-extensions: NoImplicitPrelude
35+
default-extensions: LambdaCase
36+
NoImplicitPrelude
3637
ghc-options: -Wall
3738
-Wcompat
3839
-Wincomplete-record-updates
@@ -107,6 +108,8 @@ executable cardano-timeline
107108

108109
test-suite cardano-profile-test
109110
import: project-config
111+
-- GHC9.12's warning turns to an error in CI
112+
ghc-options: -Wno-unused-imports
110113
hs-source-dirs: test/
111114
main-is: Main.hs
112115
type: exitcode-stdio-1.0

0 commit comments

Comments
 (0)