# ethereum/consensus-specs: the document and test suite every consensus client is written against

> Ethereum's consensus-layer specification, its Python reference implementation, and the compliance test vectors that decide whether a client is correct. The README assumes you already know what a fork is.

**ethereum/consensus-specs** — Ethereum Consensus Specifications

- Repository: https://github.com/ethereum/consensus-specs
- Website: https://ethereum.github.io/consensus-specs/
- Stars: 3,970 · Forks: 1,324
- Language: Python
- License: CC0-1.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/ethereum-consensus-specs

## What the repository actually hosts, stated plainly

The README's first paragraph is precise about scope: this repository hosts the Ethereum proof-of-stake specifications for consensus-layer clients. Design rationale and proposed changes are discussed in issues, agreed changes are made through pull requests, and the specifications live in `specs/`, arranged by upgrade.

The structural rule that follows is the one to internalise: each upgrade builds on the previous one and specifies only what it changes. That means `specs/altair` is not a complete document, it is a diff against Phase0 in prose and formulas. Reading a single upgrade in isolation is a mistake, and the specs table in the README makes the ordering explicit with a sequence number, a code name and a fork epoch.

Alongside `specs/` there is `configs/` for network configuration, `presets/` for preset values, `pysetup/` and `tests/` for the Python reference implementation and its test harness, and `scripts/`. The package on PyPI is `eth-consensus-specs`, currently at version 1.7.0-beta.2, requiring Python 3.12 or newer and below 3.15. That Python version floor is a real constraint for anyone wanting to run the reference implementation on an older interpreter.

## Seven stable upgrades and two that have no fork epoch yet

The stable specifications table lists Phase0 at fork epoch 0, Altair at 74240, Bellatrix at 144896, Capella at 194048, Deneb at 269568, Electra at 364032 and Fulu at 411392. Every one of those numbers is a mainnet epoch, so the table is a compact history of when the consensus layer changed and by how much.

Below that sits the unstable table with Gloas and Heze, both marked TBD for fork epoch. The distinction between stable and unstable is not cosmetic. A stable fork has a scheduled activation point on mainnet, so a client that claims to support it has a definite claim. An unstable one has spec text that exists and is being argued over, and the release notes confirm that work is happening there: v1.7.0-beta.1 includes executable gossip validation functions for heze, which is not the kind of change you make to a frozen specification.

So the repository is not a historical document. Two upgrades are actively being written while you read this. Individual features are developed in parallel under `specs/_features` and folded into an upgrade when ready, which is how most spec work actually flows.

## Reference tests are the part client developers care about most

Two links under Reference tests point at release assets and at nightly artifacts from the tests workflow. This is the mechanism by which the spec becomes executable rather than merely descriptive.

The chain of custody runs roughly like this. The Python code under `pysetup/` and `tests/core/pyspec/` is a reference implementation of the spec. The test harness derives test cases from that implementation and emits vectors that any client can run. Two independent clients that pass the same vectors are behaviourally equivalent, and a client that fails one has a bug that the spec text settles. That is a much stronger claim than code review can produce, and it is why the compliance vectors circulate more widely than the prose.

The README also points at a badge for the scheduled tests workflow, which indicates the vectors are regenerated on a timer rather than only at release. For an auditor this matters: a vector set from three weeks ago may not reflect a spec change merged yesterday.

Two external repositories are directly relevant to this testing story. `eth-ssz-specs` defines SimpleSerialize, the encoding that most of the consensus messages use, and it appears as a pinned dependency in the project metadata. Beacon APIs and Beacon Metrics define the interfaces a client exposes for testing and observability.

## Five design goals that explain most of the spec's oddities

The design goals list is short and every entry explains a class of decisions you would otherwise find baffling.

Minimize complexity, even at the cost of some losses in efficiency, is why the specification is as verbose as it is. Remain live through major network partitions and mass node outages is why liveness assumptions are stated so explicitly. Select components that are quantum-secure or easy to swap out is why the cryptography is abstracted behind function names rather than hardcoded, and it is why you find a separate cryptography specs repository. Use crypto and design techniques that support a large validator set is why aggregation and signature schemes get their own detailed treatment. And minimize hardware requirements such that a consumer laptop can participate is the goal that constrains everything else, since it rules out designs that would be more efficient on validator-grade hardware.

That last one deserves emphasis when reading the specification. It means the protocol is deliberately sized so that a non-specialist machine can run a node, which trades away efficiency in a way that looks like a mistake until you know the goal.

The README also links to the design rationale notes, a Phase0-for-humans explainer, the GHOST and Casper paper, and an annotated spec maintained separately, which is a good sign about how much effort goes into making this material readable.

## Working with the repository locally through the Makefile

There is no README section on installing, but the repository ships a Makefile whose default target prints its own documentation. The targets it advertises are the whole workflow:

```bash
make lint
make test
make comptests
```

`make test` runs the pyspec tests, which is the Python reference implementation's own suite. `make comptests` generates the compliance tests, the cross-client vectors. `make lint` runs the formatter, the spelling check, the Python linter and the static type checker.

The verbose help output spells out what `lint` actually includes: markdown formatting, a spelling checker, the ruff linter and formatter, the ty type checker, plus three repository-specific scripts for fork comments, markdown headings and note style. Those three custom checks are the interesting part, because they encode editorial rules about the spec documents that no general-purpose tool would know.

`make clean` exists too, and the Makefile warns that it removes all untracked files including the virtual environment and build artifacts. `make website` builds or serves the documentation, which is the path to reading the rendered spec locally rather than through the hosted viewer.

## CC0 licensing, external specs, and where this repository stops

The licence is CC0 1.0, a public domain dedication, and the package metadata repeats it. For a specification that multiple independent client teams must implement identically, that is the sensible choice. There is no attribution requirement, no copyleft that would force a client to expose its own source, and no field-of-use restriction. Anyone can fork it, quote it, or build a commercial product from it.

The README is equally clear about the boundary. Seven sibling repositories hold the specifications this one depends on: Beacon APIs, Beacon Metrics, Builder Specs, Cryptography Specs, the Deposit Contract, Engine APIs and SimpleSerialize Specs. If you are trying to understand how a transaction reaches the consensus layer, you need the Engine APIs repository, not this one. If you want to know how a deposit becomes a validator, you need the deposit contract. This repository holds the consensus layer's own rules.

The rendered viewers are two: a general spec viewer and the main consensus-specs site. Both are hosted on GitHub Pages under the ethereum organisation.

The repository is not archived, the last push was on 2026-09-23, and the release line moves in beta increments of several per month rather than stable releases, which tells you how tightly this tracks mainnet development.

## Conclusion

consensus-specs is the right starting point if you are writing or auditing a consensus client, because it is the only artefact all clients are required to agree on, and the compliance test vectors are the objective arbiter when two implementations disagree. It is the wrong tool for understanding Ethereum generally, since the README assumes you already know what an epoch, a fork and a validator set are, and it covers only the consensus layer, with execution-layer interfaces delegated to sibling repositories. Start at `specs/phase0` and read forward, because every later upgrade specifies only its own delta. The five design goals in the README are the honest summary of what the team optimises for, and the last one, keeping hardware requirements low enough for a consumer laptop to participate, is the constraint most likely to surprise you when reading the cryptography. The last push was on 2026-09-23 and v1.7.0-beta.2 was published the same day, so the repository tracks the active development line.

## FAQ

### How does Ethereum consensus work?

The repository states five design goals that shape the protocol: minimize complexity even at some efficiency cost, remain live through major network partitions and mass node outages, select components that are quantum-secure or easy to swap out, use techniques that support a large validator set, and keep hardware requirements low enough that a consumer laptop can participate. The full rules live in `specs/`, starting at Phase0.

### What is the difference between Phase0, Altair and later Ethereum upgrades?

Each upgrade builds on the previous one and specifies only what it changes. Phase0 is the genesis spec at fork epoch 0, and Altair, Bellatrix, Capella, Deneb, Electra and Fulu follow at scheduled epochs. Gloas and Heze are listed as unstable with fork epochs still to be determined.

### How do consensus clients prove they follow the specification?

The Python reference implementation under the pyspec test harness generates test vectors, published as release assets and as nightly artifacts from the tests workflow. Two clients that pass the same vectors behave equivalently, and a failure identifies a bug the spec text settles. `make comptests` regenerates them.

### What license does the Ethereum consensus specification use?

CC0 1.0, a public domain dedication, as stated in both the README and the package metadata. There is no attribution requirement and no copyleft, so client teams can implement it in closed-source software without obligation.

## Sources

- [ethereum/consensus-specs on GitHub](https://github.com/ethereum/consensus-specs)
- [License: CC0-1.0](https://github.com/ethereum/consensus-specs/blob/master/LICENSE)
- [Project website](https://ethereum.github.io/consensus-specs/)
- [README](https://github.com/ethereum/consensus-specs/blob/master/README.md)
- [Releases](https://github.com/ethereum/consensus-specs/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ethereum-consensus-specs
