Skip to content

Commit 739ecad

Browse files
feat(doc): re-write readme/top-level docs and add specs section to html docs (#2677)
* docs(specs): add Specs section with overview Introduce a top-level `Specs` section in the mkdocs navigation and a new `docs/specs/index.md` page that explains what EELS is, the coordination problem it solves, why Python was chosen, the Correct/Complete/Accessible principles, and the fork-as-a-copy (WET) model. This is the anchor page for further specs-side documentation (writing specs, adding a new EIP, spec releases, protocol history); those pages land in follow-up commits. * docs(specs): move protocol history table from README to Specs section The full mainnet hardfork table, the "clarifications without a protocol release" table, and the Paris/Shanghai activation note now live on a dedicated `docs/specs/protocol_history.md` page linked from the Specs overview and the mkdocs navigation. `README.md` keeps a one-line pointer to the new page. Fork-manifest links switch from repo-relative paths (`/src/ethereum/...`) to absolute GitHub URLs on `forks/amsterdam` so they resolve correctly from the rendered docs site. * docs(specs): move EIP_AUTHORS_MANUAL.md to docs/specs/adding_a_new_eip.md Pure rename so `git log --follow` (and `mkdocs-git-authors-plugin` by extension) continues to trace the file's history back to the original author, Guruprasad Kamath. Content modernization for the post-Weld world lands in the follow-up commit. * docs(specs): modernize adding_a_new_eip for the unified repo Post-Weld rewrite of the EIP author's manual. The cross-repo references to `execution-spec-tests` are replaced with pointers to in-tree tests under `./tests/`; the step-by-step workflow points at the in-tree `ethereum_spec_tools` utilities. The YouTube opcode tutorial link is preserved. The rename from `EIP_AUTHORS_MANUAL.md` to `docs/specs/adding_a_new_eip.md` was done as a pure `git mv` in the previous commit so `git log --follow` (and therefore the `mkdocs-git-authors-plugin`) continues to attribute the earlier content to its original author. Co-authored-by: Guruprasad Kamath <guru241987@gmail.com> * docs(specs): add writing_specs page from CONTRIBUTING technicals Extracts the style, comments, docstrings, constants, and cross-fork sections from `CONTRIBUTING.md` into a dedicated `docs/specs/writing_specs.md` page, alongside documentation for the `ethereum_spec_tools` CLI utilities (New Fork Tool, Sync Tool, Patch Tool, Lint Tool) and the `--evm-trace` debugging flag. The EIP-attributed-comment pitfall is preserved as a collapsible detail block so it remains readable without dominating the page. `CONTRIBUTING.md` is untouched in this commit; the slimming down to who/how/what happens in a follow-up. The `adding_a_new_eip` page gets its `Writing Specs` link back in this commit now that the target exists. * docs(contributing): slim CONTRIBUTING.md to who/how/what `CONTRIBUTING.md` now focuses on who the project welcomes contributions from, how to raise issues/PRs, and the three guiding principles (Correct, Complete, Accessible). The remaining sections point at the authoritative docs: - Environment setup, `uv`/`just`/shell completions, Python version, and the full recipe list go to `docs/getting_started/installation.md`. - Naming/comments/docstrings/constants/cross-fork discipline, and the `ethereum_spec_tools` CLI utilities go to `docs/specs/writing_specs.md`. - The `--evm-trace` debugging tip lives in `docs/specs/writing_specs.md`. - The `MYPY_CACHE_DIR` worktree tip is already covered in the installation docs. `copy_repo_docs_to_mkdocs.py` learns two new link rewrites so the repo-relative `docs/...` paths in `CONTRIBUTING.md` work both when viewed on GitHub and when the file is copied to `docs/getting_started/contributing.md` for the rendered site. * docs(specs): split RELEASING into contributor and maintainer pages The old `RELEASING.md` mixed two audiences: contributors (who want to understand the version-number scheme when reading `pyproject.toml` or proposing a release) and maintainers (who cut the tag, publish to PyPI, and file the GitHub release). Split along that seam: - `docs/specs/spec_releases.md` covers the versioning scheme (format, examples, and the current-to-next lookup table), sitting alongside the other specs-side documentation. - `docs/dev/releasing.md` is the maintainer runbook (updating the version in source, tagging, GitHub release, PyPI publish). Each page links to the other so a reader landing on either one can find the half they need. * docs(readme): rewrite README around the docs site and a Quick Start Post-Weld `README.md` becomes the GitHub-landing hook: a short description, pointers to the rendered documentation site, the `docc`-rendered pyspec, the protocol history page, a single-tab Quick Start cribbed from `docs/getting_started/installation.md`, and the license. The README now treats `docs/getting_started/installation.md` as the source of truth for environment setup: the Python-version line reflects the 3.11 to 3.14 range (recommending 3.12) rather than the stale "Python 3.11+"; the "Building Specification Documentation" and "Browsing Updated Documentation" sections collapse into a single `mkdocs serve` / `just docs-spec` note; and the "work-in-progress" placeholder heading is gone. * docs(specs): rename top-level section header to "Specifications" Use the full word "Specifications" in the navigation sidebar and the section index H1. The folder name under `docs/specs/` and the URL path are unchanged. * docs(specs): reframe coordination section around client diversity The opening section now leads with "Client Diversity requires Coordination" and frames client diversity as a positive property (resilience, no privileged implementation, permissionless participation) rather than opening on the coordination *problem*. Coordination follows as the natural consequence of that diversity: a multi-client network needs a precise shared description of behaviour, and EELS is it. Links the ethereum.org client-diversity page for readers who want the full argument. The Python-versus-prose point is kept but slimmed of incidental color ("implementation differences in early EIPs are part of the lore") that didn't add to the reframed narrative. * docs(specs): unwrap hard-wrapped paragraphs in docs/specs/ Consecutive prose lines and list-item continuations are collapsed onto a single line per paragraph / list item. Fenced code blocks, tables, HTML blocks, headings, admonition markers, blockquotes, and link reference definitions are preserved verbatim. Matches the single-line-per-paragraph style already applied to the opening paragraph of `docs/specs/index.md`, and makes the files easier to diff on prose edits. * docs(contributing): unwrap hard-wrapped paragraphs in CONTRIBUTING.md Matches the single-line-per-paragraph style now used across `docs/specs/*.md`, for cleaner future prose diffs. The blockquote content under the `[!IMPORTANT]` alert is also collapsed to a single line after the marker. * docs(contributing): point Getting Set Up at the README Quick Start `CONTRIBUTING.md` no longer embeds its own abbreviated install commands; it points at the [Quick Start](README.md#quick-start) for the short version and at the Installation guide for full setup. Avoids a third copy of the install commands drifting out of sync. `copy_repo_docs_to_mkdocs.py` rewrites `README.md#quick-start` to `installation.md#quick-start` when copying `CONTRIBUTING.md` into the mkdocs site, since the rendered site has no `README.md`. * docs(readme): unwrap paragraphs and use `just` recipes for docs builds Paragraphs are collapsed to a single line each, matching the style now used across `docs/specs/*.md` and `CONTRIBUTING.md` for cleaner future prose diffs. `mkdocs serve` is replaced with `just docs-serve-fast` so the README drives users through the repo's task runner rather than a raw `uv run` invocation; the `just docs-spec` call gets its own code block for symmetry. Both fences use the `console` language now that they are pure shell commands. * chore(docs): improve readme * chore(docs): 3.12 as default; 3.13 doesn't have coincurve wheels * chore(docs): improve contributing * chore(docs): update production client list in readme --------- Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
1 parent 6f43bc6 commit 739ecad

12 files changed

Lines changed: 605 additions & 567 deletions

CONTRIBUTING.md

Lines changed: 24 additions & 290 deletions
Original file line numberDiff line numberDiff line change
@@ -1,312 +1,46 @@
11
# Contribution Guidelines
22

3-
Help is always welcome and there are plenty of options to contribute to the Ethereum Execution Layer Specifications (EELS).
3+
Help is always welcome. The Ethereum Execution Layer Specifications (EELS) are a community effort and we appreciate support in the following areas:
44

5-
In particular, we appreciate support in the following areas:
6-
7-
- Reporting issues
8-
- Fixing and responding to [issues](https://github.com/ethereum/execution-specs/issues), especially those tagged as [E-easy](https://github.com/ethereum/execution-specs/labels/E-easy) which are meant as introductory issues for external contributors.
5+
- Reporting issues.
6+
- Fixing and responding to [issues](https://github.com/ethereum/execution-specs/issues), especially those tagged [E-easy](https://github.com/ethereum/execution-specs/labels/E-easy), which are intended as introductory issues for external contributors.
97
- Improving the documentation.
108

119
> [!IMPORTANT]
12-
> Generally, we do not assign issues to external contributors. If you want to work on an issue, you are very welcome to go ahead and make a pull request. We would, however, be happy to answer questions you may have before you start implementing.
13-
14-
For details about EELS usage and building, please refer to the [README](https://github.com/ethereum/execution-specs/blob/master/README.md#usage)
15-
16-
## Contribution Guidelines
17-
18-
This specification aims to be:
19-
20-
1. **Correct** - Describe the _intended_ behavior of the Ethereum blockchain, and any deviation from that is a bug.
21-
2. **Complete** - Capture the entirety of _consensus critical_ parts of Ethereum.
22-
3. **Accessible** - Prioritize readability, clarity, and plain language over performance and brevity.
23-
24-
### Style
25-
26-
#### Spelling and Naming
27-
28-
- Attempt to use descriptive English words (or _very common_ abbreviations) in documentation and identifiers.
29-
- Avoid using EIP numbers in identifiers, and prefer descriptive text instead (eg. `FeeMarketTransaction` instead of `Eip1559Transaction`).
30-
- If necessary, there is a custom dictionary `whitelist.txt`.
31-
- Avoid uninformative prefixes in identifiers (like `get_` or `compute_`). They don't add useful meaning and take up valuable real estate.
32-
33-
#### Comments
34-
35-
- Don't repeat what is obvious from the code.
36-
- <details>
37-
<summary><em>(expand)</em> Consider how future changes will interleave with yours, especially when creating semantic blocks.</summary>
38-
39-
<br>Consider:
40-
<table valign="top">
41-
42-
<tr valign="top">
43-
<th>Fork T</th>
44-
<th>Fork T+1</th>
45-
</tr>
46-
47-
<tr valign="top">
48-
49-
<td>
50-
51-
<!--
52-
Note that the trailing whitespace is necessary to move the copy button
53-
in the github UI over so it doesn't obscure the text.
54-
-->
55-
56-
```python
57-
# EIP-1234: The dingus is the rate of fleep
58-
dingus = a + b
59-
dingus += c ^ d
60-
dingus /= fleep(e)
61-
```
62-
63-
</td>
64-
65-
<td>
66-
67-
```python
68-
# EIP-1234: The dingus is the rate of fleep
69-
dingus = a + b
70-
71-
# EIP-4567: Frobulate the dingus
72-
dingus = frobulate(dingus)
73-
74-
dingus += c ^ d # <-
75-
dingus /= fleep(e) # <-
76-
```
77-
78-
</td>
79-
80-
</tr>
81-
82-
</table>
83-
84-
The marked lines (`<-`) are now incorrectly attributed to EIP-4567 in Fork+1. Instead, omit the EIP identifier in the comments, and describe the changes introduced by the EIP in the function's docstrings. The rendered diffs will make it pretty obvious what's changed.
85-
</details>
86-
87-
#### Docstrings
88-
89-
- Write in complete sentences, providing necessary background and context for the associated code.
90-
- Function and method docstrings must use the imperative mood in the summary line.
91-
- **Good:** Build the house using the provided lumber.
92-
- **Bad:** Builds the house using the provided lumber.
93-
- Always start with a single-line summary. When more detail is needed, use a multi-line docstring with a blank line after the summary line.
94-
- **One-line summary:**
95-
96-
```python
97-
"""Return the pathname of the KOS root directory."""
98-
```
99-
100-
- **Multi-line:**
101-
102-
```python
103-
"""
104-
Add a bloom entry to the bloom filter.
105-
106-
The number of hash functions used is 3. They are calculated by
107-
taking the least significant 11 bits from the first 3 16-bit
108-
words of the `keccak_256()` hash of `bloom_entry`.
109-
"""
110-
```
111-
112-
- Format using markdown.
113-
- Links to relevant standards and EIPs may be specified using reference-style links.
114-
115-
```python
116-
"""
117-
Minimum gas cost per byte of calldata as per [EIP-7976].
118-
119-
[EIP-7976]: https://eips.ethereum.org/EIPS/eip-7976
120-
"""
121-
```
122-
123-
- Avoid beginning docstrings with an article ("the"/"a") or a pronoun ("it", "they", etc.).
124-
- Don't include the function's signature.
125-
126-
##### Constants
127-
128-
- Do not include constant values in docstrings, neither as literals nor as expressions. It's too easy to change a constant's value and forget to update its docstring.
129-
- Construct the constant's value from other constants or meaningful expressions in order to provide meaningful context.
130-
- **Great:** `TARGET_BLOB_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET`
131-
- Composed from named constants; the reader immediately understands what the value represents.
132-
- **Acceptable:** `TX_MAX_GAS = Uint(2 ** 24)`
133-
- More readable than a raw number, but still a literal expression that doesn't convey _why_ this value was chosen.
134-
- **Bad:** `TX_MAX_GAS = Uint(16_777_216)`
135-
- A magic number with no context.
136-
137-
### Changes across various Forks
138-
139-
Many contributions require changes across multiple forks, organized under `src/ethereum/forks/*`. When making such changes, please ensure that differences between the forks are minimal and consist only of necessary differences. This will help with getting cleaner [diff outputs](https://ethereum.github.io/execution-specs/diffs/index.html).
140-
141-
When creating pull requests affecting multiple forks, we recommended submitting your PR in two steps:
142-
143-
1. Apply the changes on a single fork, open a _draft_ pull request, and get feedback; then
144-
2. Apply the changes across the other forks, push them, and mark the pull request as ready for review.
145-
146-
This saves you having to apply code review feedback repeatedly for each fork.
147-
148-
### Development
149-
150-
Running the tests necessary to merge into the repository requires:
151-
152-
- [`uv`](https://docs.astral.sh/uv/) package manager,
153-
- [`just`](https://just.systems/) command runner (install via your package manager, [`uv tool install just-bin`](https://pypi.org/project/just-bin/), or [pre-built binaries](https://just.systems/man/en/pre-built-binaries.html)),
154-
- Python 3.11.x,
155-
- [PyPy](https://www.pypy.org/) [7.3.19](https://downloads.python.org/pypy/) or later.
156-
- `geth` installed and present in `$PATH`.
157-
158-
`execution-specs` depends on a submodule that contains common tests that are run across all clients, so we need to clone the repo with the --recursive flag. Example:
159-
160-
```bash
161-
git clone --recursive https://github.com/ethereum/execution-specs.git
162-
```
163-
164-
Or, if you've already cloned the repository, you can fetch the submodules with:
165-
166-
```bash
167-
git submodule update --init --recursive
168-
```
169-
170-
The static checks can be run with:
171-
172-
```bash
173-
just static
174-
```
175-
176-
Individual checks and auto-fix are also available as recipes:
177-
178-
```bash
179-
just fix # Auto-fix formatting and lint issues.
180-
just lint # Lint with ruff.
181-
just format-check # Check formatting with ruff.
182-
just typecheck # Run type checking with mypy.
183-
just spellcheck # Check spelling with codespell.
184-
```
185-
186-
Run `just` to see all available recipes. Recipes that accept arguments can be passed extra flags, for example:
187-
188-
```bash
189-
just typecheck --warn-unreachable
190-
```
191-
192-
> [!TIP]
193-
> If you use multiple git worktrees, set `MYPY_CACHE_DIR` to share a single
194-
> mypy cache across all of them and avoid cold-start delays:
195-
>
196-
> ```bash
197-
> export MYPY_CACHE_DIR=~/path/to/execution-specs/.mypy_cache
198-
> ```
199-
200-
### Shell Auto-Completion
201-
202-
`just` provides tab-completion for recipe names and arguments. To enable it for your shell:
203-
204-
**Bash** — add to `~/.bashrc`:
205-
206-
```bash
207-
eval "$(just --completions bash)"
208-
```
209-
210-
**Zsh** — add to `~/.zshrc`:
211-
212-
```bash
213-
eval "$(just --completions zsh)"
214-
```
215-
216-
**Fish** — run once (fish auto-loads completions from this directory):
217-
218-
```bash
219-
just --completions fish > ~/.config/fish/completions/just.fish
220-
```
221-
222-
After restarting your shell (or sourcing the config), `just <Tab>` will complete recipe names.
223-
224-
A trace of the EVM execution for any test case can be obtained by providing the `--evm-trace` argument to pytest.
225-
Note: Make sure to run the EVM trace on a small number of tests at a time. The log might otherwise get very big.
226-
Below is an example.
227-
228-
```bash
229-
uv run pytest \
230-
'tests/json_loader/test_state_tests.py::test_state_tests_frontier[stAttackTest - ContractCreationSpam - 0]' \
231-
--evm_trace
232-
```
233-
234-
## CLI Utilities `ethereum_spec_tools`
235-
236-
The EELS repository has various CLI utilities that can help in the development process.
237-
238-
### New Fork Tool
239-
240-
This tool can be used to create the base code for a new fork by using the existing code from a given fork.
241-
242-
The command takes 4 arguments, 2 of which are optional
243-
244-
- from_fork: The fork name from which the code is to be duplicated. Eg. - "Tangerine Whistle"
245-
- to_fork: The fork name of the new fork Eg - "Spurious Dragon"
246-
- from_test (Optional): Name of the from fork within the test fixtures in case it is different from fork name. Eg. - "EIP150"
247-
- to_test (Optional): Name of the to fork within the test fixtures in case it is different from fork name Eg - "EIP158"
248-
249-
As an example, if one wants to create baseline code for the `Spurious Dragon` fork from the `Tangerine Whistle` one
250-
251-
```bash
252-
uv run ethereum-spec-new-fork --from_fork="Tangerine Whistle" --to_fork="Spurious Dragon" --from_test=EIP150 --to_test=EIP158
253-
```
254-
255-
The following will have to however, be updated manually
256-
257-
1. The fork number and `MAINNET_FORK_BLOCK` in `__init__.py`. If you are proposing a new EIP, please set `MAINNET_FORK_BLOCK` to `None`.
258-
2. Any absolute package imports from other forks eg. in `trie.py`
259-
3. Package names under `setup.cfg`
260-
4. Add the new fork to the `monkey_patch()` function in `src/ethereum_optimized/__init__.py`
261-
5. Adjust the underline in `fork/__init__.py`
10+
> Generally, we do not assign issues to external contributors. If you want to work on an issue, you are welcome to go ahead and make a pull request. We are happy to answer questions before you start implementing.
26211
263-
### Sync Tool
12+
## Contributions we don't accept
26413

265-
The sync tool allows one to use an RPC provider to fetch and validate blocks against EELS.
266-
The state can also be stored in a local DB after validation. Since syncing directly with the specs can be
267-
very slow, one can also leverage the optimized module. This contains alternative implementations of routines
268-
in EELS that have been optimized for speed rather than clarity/readability.
14+
Pull requests should have reasonable substance and context. In particular, we do not accept:
26915

270-
The tool can be called using the `ethereum-spec-sync` command which takes the following arguments
16+
- Contributions that only fix spelling or grammatical errors in documentation, code, or elsewhere.
17+
- Drive-by or vibe-coded contributions without proper engagement or context.
27118

272-
- rpc-url: Endpoint providing the Ethereum RPC API. Defaults to `http://localhost:8545/`
273-
- unoptimized: Don't use the optimized state/ethash (this can be extremely slow)
274-
- persist: Store the state in a db in this file
275-
- geth: Use geth specific RPC endpoints while fetching blocks
276-
- reset: Delete the db and start from scratch
277-
- gas-per-commit: Commit to db each time this much gas is consumed. Defaults to 1_000_000_000
278-
- initial-state: Start from the state in this db, rather than genesis
279-
- stop-at: After syncing this block, exit successfully
19+
## Code of Conduct
28020

281-
- The following options are not supported WITH `--unoptimized` -> `--persist`, `--initial-state`, `--reset`
282-
- The following options are not supported WITHOUT `--persist` -> `--initial_state`, `--reset`
21+
All contributors are expected to be excellent to each other; other behavior is not tolerated. To report a concern, contact one of the [STEEL team members](https://steel.ethereum.foundation/team/).
28322

284-
### Patch Tool
23+
## Principles
28524

286-
This tool can be used to apply the unstaged changes in `SOURCE_FORK` to each of the `TARGET_FORKS`. If some
287-
of the change didn't apply, '.rej' files listing the unapplied changes will be left in the `TARGET_FORK`.
25+
The specification aims to be:
28826

289-
The tool takes the following command line arguments
27+
1. **Correct.** Describe the *intended* behavior of the Ethereum blockchain. Any deviation from that is a bug.
28+
2. **Complete.** Capture the entirety of *consensus-critical* parts of Ethereum.
29+
3. **Accessible.** Prioritize readability, clarity, and plain language over performance and brevity.
29030

291-
- The fork name where the changes have been made. Eg:- `frontier` (only a single fork name)
292-
- The fork names where the changes have to be applied. Eg:- `homestead` (multiple values can be provided separated by space)
293-
- optimized: Patch the optimized code instead
294-
- tests: Patch the tests instead
31+
## Getting set up
29532

296-
As an example, if one wants to apply changes made in `Frontier` fork to `Homestead` and `Tangerine Whistle`
33+
Environment setup (cloning the repository, installing `uv` and `just`, Python requirements) is documented in the [Installation guide](docs/getting_started/installation.md).
29734

298-
```bash
299-
uv run python src/ethereum_spec_tools/patch_tool.py frontier homestead tangerine_whistle
300-
```
35+
Before opening a PR, run the checks relevant to your change; see [Verifying Changes](docs/getting_started/verifying_changes.md).
30136

302-
### Lint Tool
37+
## Changes that affect multiple forks
30338

304-
This tool checks for style and formatting issues specific to EELS and emits diagnostics
305-
when issues are found
39+
When creating pull requests that touch several forks under `src/ethereum/forks/`, we recommend a two-step workflow:
30640

307-
The tool currently performs the following checks
41+
1. Apply the changes on a single fork, open a *draft* PR, and get feedback.
42+
2. Apply the changes across the other forks, push them, and mark the PR as ready for review.
30843

309-
- The order of the identifiers between each hardfork is consistent.
310-
- Import statements follow the relevant import rules in modules.
44+
This saves you from applying code review feedback repeatedly for each fork.
31145

312-
The command to run the tool is `just lint-spec` (or `uv run ethereum-spec-lint`).
46+
See [Writing Specs](docs/specs/writing_specs.md) for the technical style rules (naming, comments, docstrings, constants, cross-fork discipline) and for the `ethereum_spec_tools` CLI utilities that help with these workflows.

0 commit comments

Comments
 (0)