Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first draft of a CONTRIBUTING document
* Some sections of the main README have been moved to a new CONTRIBUTING document. * Added a coding conventions section to the CONTRIBUTING document. * Added performanc section to the CONTRIBUTING document.
- Loading branch information
Jared Corduan
committed
Jan 10, 2022
1 parent
50e9e2b
commit c048433
Showing
2 changed files
with
306 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
# Contributing to the Cardano Ledger | ||
|
||
## Building | ||
|
||
See the [Readme](https://github.com/input-output-hk/cardano-ledger#building) for instructions on building. | ||
|
||
## Warnings | ||
|
||
While building most compilation warnings will be turned into an error due to | ||
`-Werror` flag. However during development it might be a bit inconvenient thus | ||
can be disabled on per project basis: | ||
|
||
```shell | ||
cabal configure <package-name> --ghc-options="-Wwarn" | ||
cabal build <package-name> | ||
``` | ||
|
||
## Testing the Haskell programs | ||
|
||
The tests can be run with cabal. | ||
For example the Shelley tests can be run with: | ||
|
||
```shell | ||
cabal test cardano-ledger-shelley-test | ||
``` | ||
|
||
**Note** that the tests in `cardano-ledger-shelley-test` require two Ruby gems, | ||
[cbor-diag](https://rubygems.org/gems/cbor-diag) and | ||
[cddl](https://rubygems.org/gems/cddl). | ||
|
||
It can be helpful to use the `--test-show-details=streaming` option for seeing | ||
the output of the tests while they run: | ||
|
||
```shell | ||
cabal test cardano-ledger-shelley-test --test-show-details=streaming | ||
``` | ||
|
||
### Running Specific Tests | ||
|
||
The test suites use [Tasty](https://github.com/feuerbach/tasty), | ||
which allows for running specific tests. | ||
This is done by passing the `-p` flag to the test program, followed by an `awk` pattern. | ||
You can alternatively use the `TASTY_PATTERN` environment variable with a pattern. | ||
For example, the Shelley golden tests can be run with: | ||
|
||
```shell | ||
cabal test cardano-ledger-shelley-test --test-options="-p golden" | ||
``` | ||
|
||
or | ||
|
||
```shell | ||
TASTY_PATTERN=golden cabal test cardano-ledger-shelley-test | ||
``` | ||
|
||
`Tasty` allows for more | ||
[complex patterns](https://github.com/feuerbach/tasty#patterns). | ||
For instance, to run only the Byron update mechanism tests for the ledger | ||
that classify traces, we can pass the | ||
`-p $1 ~ /Ledger/ && $2 ~ /Update/ && $3 ~ /classified/` option. | ||
Here each `$i` refers to a level in the tests names hierarchy. | ||
Passing `-l` to `tasty` will list the available test names. | ||
|
||
When testing using `cabal`, pay special attention to escaping the right symbols, e.g.: | ||
|
||
```shell | ||
cabal test byron-spec-ledger:test:byron-spec-ledger-test --test-options "-p \"\$1 ~ /Ledger/ && \$2 ~ /Update/ && \$3 ~ /classified/\"" | ||
``` | ||
|
||
### Replaying QuickCheck Failures | ||
|
||
When a QuickCheck test fails, the seed which produced the failure is reported. | ||
The failure can be replayed with: | ||
|
||
```shell | ||
cabal test cardano-ledger-shelley-test --test-options "--quickcheck-replay=42" | ||
``` | ||
(where 42 is an example seed). | ||
|
||
### Test Scenarios | ||
|
||
Most of the test suites are grouped into test scenarios. | ||
For example, the Shelley test suite contains | ||
`ContinuousIntegration`, `Development`, `Nightly`, and `Fast`, | ||
which can be run with the `--scenario` flag. For example: | ||
|
||
```shell | ||
cabal test cardano-ledger-shelley-test --test-options --scenario=Fast | ||
``` | ||
|
||
### ghcid | ||
|
||
We have support for running | ||
[ghcid](https://github.com/ndmitchell/ghcid) | ||
from inside of nix-shell. | ||
Enter nix-shell from the base directory of the repository, | ||
change directories to the cabal package that you wish to check, | ||
then run `ghcid`. | ||
|
||
For example: | ||
|
||
```shell | ||
nix-shell | ||
cd eras/shelley/impl/ | ||
ghcid | ||
``` | ||
|
||
--- | ||
|
||
## nix-build Infrastructure | ||
|
||
The artifacts in this repository can be built and tested using nix. This is | ||
additionally used by the Hydra CI to test building, including cross-compilation | ||
for other systems. | ||
|
||
### To add a new Haskell project | ||
|
||
To add a new Haskell project, you should do the following: | ||
|
||
1. Create the project in the usual way. It should have an appropriate `.cabal` file. | ||
2. Add the project to the [top-level stack.yaml](./stack.yaml), configuring | ||
dependencies etc as needed. If your project's configuration deviates too far | ||
from the [snapshot in | ||
``cardano-prelude`](https://github.com/input-output-hk/cardano-prelude/blob/master/snapshot.yaml), | ||
then you may have to submit a PR there to update that snapshot. | ||
3. At this point, test that your new project builds using `stack build <project_name>`. | ||
4. Run [nix-shell ./nix -A iohkNix.stack-cabal-sync-shell --run scripts/stack-cabal_config_check.sh](./scripts/stack-cabal_config_check.sh) | ||
script to check and report your change from stack.yaml to cabal.project. | ||
5. Run the [regenerate](./nix/regenerate.sh) script to | ||
update sha256 checksums in cabal.project. | ||
5. Test that you can build your new project by running the following: `nix build | ||
-f default.nix libs.<project_name>`. If you have executables, then | ||
you may also try building these using the `exes.<executable_name>` | ||
attribute path. A good way to see what's available is to execute `:l | ||
default.nix` in `nix repl`. This will allow you to explore the potential | ||
attribute names. | ||
5. If you want your product to be tested by CI, add it to | ||
[release.nix](./release.nix) using the format specified in that file. | ||
|
||
### To add a new LaTeX specification | ||
|
||
To add a new LaTeX specification, the easiest way is to copy from one of the | ||
existing specifications. You will want the `Makefile` and `default.nix` (say | ||
from [the Shelley ledger spec](./eras/shelley/formal-spec)). | ||
|
||
1. Copy these files into the root of your new LaTeX specification. | ||
2. Modify the `DOCNAME` in the `Makefile`. | ||
3. Update `default.nix` to: | ||
1. Make sure that the relative path in the first line is pointing to | ||
(default.nix)[./default.nix]. This is used to pin the | ||
`nixpkgs` version used to build the LaTeX specifications. | ||
2. Update the `buildInputs` to add in any LaTeX packages you need in your | ||
document, and remove any unneeded ones. | ||
3. Alter the `meta` description field to reflect the nature of this document. | ||
4. Add a link to the package at the bottom of [default.nix](./default.nix), | ||
following the existing examples. | ||
5. To require that your specification be built in CI, add it at the end of the | ||
list in [default.nix](./default.nix) following the existing examples. | ||
|
||
### Additional documentation | ||
|
||
You can find additional documentation on the nix infrastructure used in this | ||
repo in the following places: | ||
|
||
- [The haskell.nix user guide](https://github.com/input-output-hk/haskell.nix/blob/documentation/docs/user-guide.md) | ||
- [The nix-tools repository](https://github.com/input-output-hk/nix-tools) | ||
- [The iohk-nix repository](https://github.com/input-output-hk/iohk-nix) | ||
|
||
Note that the user guide linked above is incomplete and does not correctly refer | ||
to projects built using `iohk-nix`, as this one is. A certain amount of trial | ||
and error may be required to make substantive changes! | ||
|
||
<p align="center"> | ||
<a href="https://github.com/input-output-hk/cardano-ledger-specs/blob/master/LICENSE"> | ||
<img src="https://img.shields.io/github/license/input-output-hk/cardano-ledger-specs.svg?style=for-the-badge"/> | ||
</a> | ||
</p> | ||
|
||
## Working Conventions | ||
|
||
### Code formatting | ||
|
||
We use [`ormolu`](https://github.com/tweag/ormolu/) for formatting. | ||
There is a script [here](https://github.com/input-output-hk/cardano-ledger-specs/blob/master/scripts/ormolise.sh) | ||
which uses nix to format the appropriate directories. | ||
|
||
### Compiler warnings | ||
|
||
The CI builds Haskell code with -Werror, so will fail if there are any compiler warnings. | ||
|
||
If the warnings are stupid, we can turn them off, e.g. sometimes it makes sense to add -Wno-orphans So fix your own warnings://github.com/input-output-hk/plutus/blob/master/CONTRIBUTING.adoc#commit-messages to a file where we know it’s safe. | ||
|
||
### Commit messages | ||
|
||
Summarize changes in around 50 characters or less. | ||
|
||
Provide more detailed explanatory text, if necessary. | ||
Wrap it to about 72 characters or so. | ||
In some contexts, the first line is treated as the | ||
subject of the commit and the rest of the text as the body. | ||
The blank line separating the summary from the body is critical | ||
(unless you omit the body entirely); | ||
various tools like `log`, `shortlog` and `rebase` can get | ||
confused if you run the two together. | ||
|
||
Explain the problem that this commit is solving. | ||
Focus on why you are making this change as opposed to how (the code explains that). | ||
Are there side effects or other unintuitive consequences of this | ||
change? Here's the place to explain them. | ||
|
||
Further paragraphs come after blank lines. | ||
|
||
- Bullet points are okay, too | ||
|
||
- Typically a hyphen or asterisk is used for the bullet, preceded | ||
by a single space, with blank lines in between, but conventions | ||
vary here | ||
|
||
If you use an issue tracker, put references to them at the bottom, | ||
like this: | ||
|
||
Resolves: #123 | ||
See also: #456, #789 | ||
|
||
### Commit signing | ||
|
||
Commits are required to be [signed](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits). | ||
|
||
### Pull Requests | ||
|
||
Keep commits to a single logical change where possible. | ||
The reviewer will be happier, and you’ll be happier if you ever have to revert it. | ||
If you can’t do this (say because you have a huge mess), best to just have one commit with everything in it. | ||
|
||
Keep your PRs to a single topic. | ||
Including unrelated changes makes things harder for your reviewers, slowing them down, and makes it harder to integrate new changes. | ||
|
||
If you’re working on something that’s likely to conflict with someone else, talk to them. It’s not a race. | ||
|
||
## Performance | ||
|
||
### Memory | ||
|
||
The [ledger-state](https://github.com/input-output-hk/cardano-ledger/tree/master/libs/ledger-state) | ||
tool is helpful for obverserving the memory overhead of the ledger state. | ||
|
||
### Profiling | ||
|
||
A good way to profile the ledger code is to use the | ||
[db-analyser](https://github.com/input-output-hk/ouroboros-network/blob/master/ouroboros-consensus-cardano/tools/db-analyser/Documentation.md) | ||
to replay block validation from mainnet. | ||
|
||
First, inside the ouroboros repository base directory, | ||
open a nix shell with profiling enabled: | ||
``` | ||
~/ouroboros-network$ nix-shell --arg config "{ haskellNix.profiling = true; }" | ||
``` | ||
|
||
Configure cabal to build everything with profiling enabled: | ||
``` | ||
cabal configure --enable-profiling --profiling-detail=all-functions | ||
``` | ||
|
||
Now we need to run a node to build up the dataabase. | ||
This can be done in the cardano-node repository by | ||
opening a nix-shell and running: | ||
``` | ||
nix build -f default.nix scripts.mainnet.node | ||
./result/bin/cardano-node-mainnet | ||
``` | ||
This will take a very long time. | ||
You can stop the node once it is past any slots that you care about. | ||
|
||
Chaing directories back to ouroboros-network. | ||
Download the [mainnet config files](https://hydra.iohk.io/job/Cardano/iohk-nix/cardano-deployment/latest-finished/download/1/index.html). | ||
|
||
Create a snapshot at the slot that you wish the profiling to start. We use 45288084 in this example: | ||
|
||
``` | ||
cabal run db-analyser -- --db ~/io/cardano-node/state-node-mainnet/db-mainnet/ --minimum-block-validation cardano --configByron mainnet-byron-genesis.json --configShelley mainnet-shelley-genesis.json --nonce 1a3be38bcbb7911969283716ad7aa550250226b76a61fc51cc9a9a35d9276d81 --configAlonzo mainnet-alonzo-genesis.json --only-immutable-db --store-ledger 45288084 | ||
``` | ||
|
||
The value of the nonce used above can be discovered in the | ||
[config]('https://github.com/input-output-hk/cardano-node/blob/61da26bddd4d34a5ec750492aa625c62941d808a/configuration/cardano/mainnet-config.json#L15a). | ||
|
||
Finally, | ||
|
||
Run the block validation, say for 1000 slots, with: | ||
``` | ||
cabal run db-analyser -- --db <PATH_TO_NODE>/cardano-node/state-node-mainnet/db-mainnet/ --minimum-block-validation cardano --configByron mainnet-byron-genesis.json --configShelley mainnet-shelley-genesis.json --configAlonzo mainnet-alonzo-genesis.json --only-immutable-db --analyse-from 45288084 --num-blocks-to-process 1000 --trace-ledger +RTS -pj -l-agu -RTS | ||
``` | ||
|
||
This produces the profiling file `db-analyser.prof`. | ||
|
||
### Odds and Ends | ||
|
||
See the [wiki](https://github.com/input-output-hk/cardano-ledger/wiki) for some other odds and ends. |
Oops, something went wrong.