eth-ssz-specs 0.0.1.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,168 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ Pipfile.lock
88
+
89
+ # poetry
90
+ poetry.lock
91
+
92
+ # pdm
93
+ .pdm.toml
94
+ .pdm-python
95
+ .pdm-build/
96
+
97
+ # PEP 582
98
+ __pypackages__/
99
+
100
+ # Celery stuff
101
+ celerybeat-schedule
102
+ celerybeat.pid
103
+
104
+ # SageMath parsed files
105
+ *.sage.py
106
+
107
+ # Environments
108
+ .env
109
+ .venv
110
+ env/
111
+ venv/
112
+ ENV/
113
+ env.bak/
114
+ venv.bak/
115
+
116
+ # Spyder project settings
117
+ .spyderproject
118
+ .spyproject
119
+
120
+ # Rope project settings
121
+ .ropeproject
122
+
123
+ # mkdocs documentation
124
+ /site
125
+
126
+ # mypy
127
+ .mypy_cache/
128
+ .dmypy.json
129
+ dmypy.json
130
+
131
+ # Pyre type checker
132
+ .pyre/
133
+
134
+ # pytype static type analyzer
135
+ .pytype/
136
+
137
+ # Cython debug symbols
138
+ cython_debug/
139
+
140
+ # IDEs
141
+ .idea/
142
+ .vscode/
143
+ *.swp
144
+ *.swo
145
+ *~
146
+ .DS_Store
147
+
148
+ # Test fixtures output
149
+ fixtures/
150
+
151
+ # UV
152
+ .uv/
153
+
154
+ # Ruff
155
+ .ruff_cache/
156
+
157
+ # Claude Code
158
+ .claude/settings.local.json
159
+
160
+ # Local agent worktrees
161
+ .claude/worktrees/
162
+
163
+ # Local Claude Code config (not tracked)
164
+ .claude/
165
+
166
+ # Packaged release test vectors
167
+ ssz-test-vectors-*.tar.gz
168
+ ssz-test-vectors-*.tar.gz.sha256
@@ -0,0 +1,59 @@
1
+ # Contributing to SSZ Specs
2
+
3
+ ## Quick Start
4
+
5
+ 1. Fork and clone the repository
6
+ 2. Install dependencies: `uv sync`
7
+ 3. Make your changes
8
+ 4. Install `just`: `uv tool install just-bin`
9
+ 5. Run checks: `just check`
10
+ 6. Run tests: `just test`
11
+ 7. Submit a pull request
12
+
13
+ ## Pull Request Guidelines
14
+
15
+ 1. **Create a feature branch**: `git checkout -b feat/your-feature-name`
16
+ 2. **Write clear commit messages** that explain what and why
17
+ 3. **Add tests** for any new functionality
18
+ 4. **Update documentation** as needed
19
+ 5. **Ensure all checks pass** before submitting
20
+
21
+ ## Code Style
22
+
23
+ - **Type hints**: Required for all functions and methods
24
+ - **Docstrings**: Use Google style for public APIs
25
+ - **Line length**: 100 characters (enforced by ruff)
26
+ - **Formatting**: Run `just fix` to auto-format
27
+
28
+ ## Testing
29
+
30
+ - Write tests that mirror the source structure
31
+ - Use `pytest.mark.parametrize` for multiple test cases
32
+ - Mark slow tests with `@pytest.mark.slow`
33
+
34
+ ## Cutting a Release
35
+
36
+ 1. Open a PR bumping `version` in both `pyproject.toml` and
37
+ `packages/testing/pyproject.toml` (they must match).
38
+ 2. Merge it, then run Actions → Release → Run workflow on `main`.
39
+
40
+ The workflow runs the quality gate, packages the vectors, builds the package, tags
41
+ `v<version>` with a GitHub release, and publishes `eth-ssz-specs` to PyPI. Versions
42
+ other than plain `X.Y.Z` (e.g. `0.2.0rc1`) become GitHub prereleases. `ssz-testing`
43
+ is internal and never published.
44
+
45
+ If anything fails before the release job, no tag was created: fix and re-dispatch. If
46
+ only the PyPI publish fails, re-run the failed job on the same run instead.
47
+
48
+ Before the first release: add a PyPI trusted publisher (project `eth-ssz-specs`, owner
49
+ `leanEthereum`, repository `ssz-specs`, workflow `release.yaml`, environment `pypi`)
50
+ and create the `pypi` environment in the GitHub repository settings.
51
+
52
+ Reproduce the artifacts locally with `just build` and `just pack-fixtures <tag>`
53
+ (macOS: `brew install gnu-tar coreutils`).
54
+
55
+ ## Questions?
56
+
57
+ - Check existing [issues](https://github.com/ethereum/ssz-specs/issues)
58
+ - Open a new issue for discussion
59
+ - See [README.md](README.md) for more details on the project structure and commands
@@ -0,0 +1,135 @@
1
+ set positional-arguments := true
2
+
3
+ alias help := default
4
+
5
+ # List available recipes
6
+ default:
7
+ @just --list
8
+
9
+ # Run all quality checks (lint, format, typecheck, spellcheck, lock)
10
+ [group('quality')]
11
+ check: lint format-check typecheck spellcheck lock-check
12
+
13
+ # Lint with ruff (no auto-fix)
14
+ [group('quality')]
15
+ lint *args:
16
+ uv run --group lint ruff check --no-fix --show-fixes "$@"
17
+
18
+ # Format code with ruff
19
+ [group('quality')]
20
+ format *args:
21
+ uv run --group lint ruff format "$@"
22
+
23
+ # Verify formatting with ruff (no changes)
24
+ [group('quality')]
25
+ format-check *args:
26
+ uv run --group lint ruff format --check "$@"
27
+
28
+ # Auto-fix lint and formatting issues
29
+ [group('quality')]
30
+ fix:
31
+ uv run --group lint ruff check --fix
32
+ uv run --group lint ruff format
33
+
34
+ # Type check with ty
35
+ [group('quality')]
36
+ typecheck *args:
37
+ uv run --group lint ty check "$@"
38
+
39
+ # Spell check source, tests, and packages
40
+ [group('quality')]
41
+ spellcheck *args:
42
+ uv run --group lint codespell src tests packages README.md --skip="*.lock,*.svg,.git,__pycache__,.pytest_cache" "$@"
43
+
44
+ # Verify uv.lock is up to date
45
+ [group('quality')]
46
+ lock-check:
47
+ #!/usr/bin/env bash
48
+ if ! uv lock --check; then
49
+ echo ""
50
+ echo "uv.lock is out of date. To sync:"
51
+ echo " uv lock"
52
+ echo ""
53
+ echo "Then commit the updated uv.lock."
54
+ exit 1
55
+ fi
56
+
57
+ # Generate SSZ conformance test vectors under fixtures/
58
+ [group('fill')]
59
+ fill *args:
60
+ uv run --group test fill --clean "$@"
61
+
62
+ # Run unit tests in parallel
63
+ [group('tests')]
64
+ test *args:
65
+ uv run --group test pytest tests -n auto --maxprocesses=10 --durations=10 --dist=worksteal "$@"
66
+
67
+ # Run unit tests with coverage report (HTML + terminal)
68
+ [group('tests')]
69
+ test-cov *args:
70
+ uv run --group test pytest --cov --cov-report=html --cov-report=term "$@"
71
+
72
+ # Run unit tests with coverage gate (fails below 100%)
73
+ [group('tests')]
74
+ test-cov-gate *args:
75
+ uv run --group test pytest --cov --cov-report=term-missing --cov-fail-under=100 "$@"
76
+
77
+ # Build the eth-ssz-specs sdist and wheel into dist/
78
+ [group('release')]
79
+ build:
80
+ uv build
81
+
82
+ # Fill vectors and package them as a versioned, deterministic release tarball
83
+ # (requires GNU tar and sha256sum; on macOS: brew install gnu-tar coreutils)
84
+ [group('release')]
85
+ pack-fixtures tag: fill
86
+ #!/usr/bin/env bash
87
+ set -euo pipefail
88
+ TAR=tar
89
+ SHA256=sha256sum
90
+ if [ "$(uname)" = "Darwin" ]; then
91
+ command -v gtar >/dev/null || { echo "GNU tar required: brew install gnu-tar" >&2; exit 1; }
92
+ TAR=gtar
93
+ command -v sha256sum >/dev/null || SHA256="shasum -a 256"
94
+ fi
95
+ "$TAR" --sort=name --owner=0 --group=0 --numeric-owner \
96
+ --mtime='@0' --format=gnu \
97
+ --use-compress-program='gzip --no-name' \
98
+ --create --file="ssz-test-vectors-{{tag}}.tar.gz" fixtures
99
+ $SHA256 "ssz-test-vectors-{{tag}}.tar.gz" > "ssz-test-vectors-{{tag}}.tar.gz.sha256"
100
+
101
+ # Print the command to install shell completions for just recipes
102
+ [group('housekeeping')]
103
+ shell-completions:
104
+ #!/usr/bin/env bash
105
+ case "$(basename "$SHELL")" in
106
+ bash)
107
+ echo "Run the following commands to install just completions for bash:"
108
+ echo ""
109
+ echo " mkdir -p ~/.local/share/bash-completion/completions"
110
+ echo " just --completions bash > ~/.local/share/bash-completion/completions/just"
111
+ ;;
112
+ zsh)
113
+ echo "Run the following commands to install just completions for zsh:"
114
+ echo ""
115
+ echo " mkdir -p ~/.zsh/completions"
116
+ echo " just --completions zsh > ~/.zsh/completions/_just"
117
+ echo ""
118
+ echo "Then add to your .zshrc:"
119
+ echo ""
120
+ echo " fpath=(~/.zsh/completions \$fpath)"
121
+ echo " autoload -U compinit"
122
+ echo " compinit"
123
+ ;;
124
+ fish)
125
+ echo "Run the following commands to install just completions for fish:"
126
+ echo ""
127
+ echo " mkdir -p ~/.config/fish/completions"
128
+ echo " just --completions fish > ~/.config/fish/completions/just.fish"
129
+ ;;
130
+ *)
131
+ echo "See the link below for instructions for your shell."
132
+ ;;
133
+ esac
134
+ echo ""
135
+ echo "For more details, see https://just.systems/man/en/shell-completion-scripts.html"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ethereum Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.4
2
+ Name: eth-ssz-specs
3
+ Version: 0.0.1.dev1
4
+ Summary: Ethereum SSZ (Simple Serialize) specification and Merkleization
5
+ Project-URL: Homepage, https://github.com/ethereum/ssz-specs
6
+ Project-URL: Source, https://github.com/ethereum/ssz-specs
7
+ Project-URL: Issues, https://github.com/ethereum/ssz-specs/issues
8
+ Author-email: Ethereum Foundation <security@ethereum.org>
9
+ License: MIT License
10
+
11
+ Copyright (c) 2025 Ethereum Foundation
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: ethereum,merkleization,simple-serialize,specifications,ssz
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Classifier: Programming Language :: Python :: 3.13
36
+ Classifier: Programming Language :: Python :: 3.14
37
+ Requires-Python: >=3.12
38
+ Requires-Dist: pydantic<3,>=2.12.0
39
+ Requires-Dist: typing-extensions>=4.4
40
+ Description-Content-Type: text/markdown
41
+
42
+ # SSZ Specs
43
+
44
+ Simple Serialize (SSZ) is a serialization and hashing scheme used by Ethereum.
45
+ This project is a reference implementation written in Python which serves as the
46
+ official specifications.
47
+
48
+ ## Development
49
+
50
+ This project uses [`uv`](https://docs.astral.sh/uv/) and
51
+ [`just`](https://just.systems/).
52
+
53
+ ```bash
54
+ just check # Run code quality checks
55
+ just fix # Run code quality fixers
56
+ just test # Run unit tests
57
+ just fill # Generate reference tests
58
+ ```
59
+
60
+ ## Tests
61
+
62
+ This project generates JSON reference tests, included in each release, that SSZ
63
+ implementations can run to ensure compliance with the specifications.
64
+
65
+ ## Releases
66
+
67
+ Each release ships the `eth-ssz-specs` package on PyPI and the reference tests on the
68
+ [releases page](https://github.com/leanEthereum/ssz-specs/releases), both built from
69
+ the tagged commit.
70
+
71
+ ```bash
72
+ pip install eth-ssz-specs
73
+ ```
74
+
75
+ ```bash
76
+ TAG=v0.1.0
77
+ curl -sSLO "https://github.com/leanEthereum/ssz-specs/releases/download/$TAG/ssz-test-vectors-$TAG.tar.gz"
78
+ curl -sSLO "https://github.com/leanEthereum/ssz-specs/releases/download/$TAG/ssz-test-vectors-$TAG.tar.gz.sha256"
79
+ sha256sum --check "ssz-test-vectors-$TAG.tar.gz.sha256"
80
+ tar -xzf "ssz-test-vectors-$TAG.tar.gz" # extracts fixtures/
81
+ ```
82
+
83
+ ## Types
84
+
85
+ ### `Boolean`
86
+
87
+ A true or false value.
88
+
89
+ ```python
90
+ Boolean(True)
91
+ ```
92
+
93
+ ### `Bit`
94
+
95
+ A zero or one value.
96
+
97
+ ```python
98
+ Bit(1)
99
+ ```
100
+
101
+ ### `Byte`
102
+
103
+ Eight bits of opaque data.
104
+
105
+ ```python
106
+ Byte(0xFF)
107
+ ```
108
+
109
+ ### `Uint8`
110
+
111
+ An 8-bit unsigned integer.
112
+
113
+ ```python
114
+ Uint8(0xFF)
115
+ ```
116
+
117
+ ### `Uint16`
118
+
119
+ A 16-bit unsigned integer.
120
+
121
+ ```python
122
+ Uint16(0xFFFF)
123
+ ```
124
+
125
+ ### `Uint32`
126
+
127
+ A 32-bit unsigned integer.
128
+
129
+ ```python
130
+ Uint32(0xFFFFFFFF)
131
+ ```
132
+
133
+ ### `Uint64`
134
+
135
+ A 64-bit unsigned integer.
136
+
137
+ ```python
138
+ Uint64(0xFFFFFFFFFFFFFFFF)
139
+ ```
140
+
141
+ ### `Uint128`
142
+
143
+ A 128-bit unsigned integer.
144
+
145
+ ```python
146
+ Uint128(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
147
+ ```
148
+
149
+ ### `Uint256`
150
+
151
+ A 256-bit unsigned integer.
152
+
153
+ ```python
154
+ Uint256(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
155
+ ```
156
+
157
+ ### `Vector`
158
+
159
+ A fixed number of elements.
160
+
161
+ ```python
162
+ class Color(Vector[Uint8]):
163
+ LENGTH = 3
164
+
165
+ Color(data=[255, 128, 0])
166
+ ```
167
+
168
+ ### `List`
169
+
170
+ A variable number of elements up to a limit.
171
+
172
+ ```python
173
+ class Scores(List[Uint64]):
174
+ LIMIT = 8
175
+
176
+ Scores(data=[10, 20, 30])
177
+ ```
178
+
179
+ ### `ByteVector`
180
+
181
+ A fixed number of bytes.
182
+
183
+ ```python
184
+ class Serial(ByteVector):
185
+ LENGTH = 4
186
+
187
+ Serial(b"\x01\x02\x03\x04")
188
+ ```
189
+
190
+ ### `ByteList`
191
+
192
+ A variable number of bytes up to a limit.
193
+
194
+ ```python
195
+ class Message(ByteList):
196
+ LIMIT = 32
197
+
198
+ Message(data=b"hello")
199
+ ```
200
+
201
+ ### `BitVector`
202
+
203
+ A fixed number of bits.
204
+
205
+ ```python
206
+ class Weekdays(BitVector):
207
+ LENGTH = 7
208
+
209
+ Weekdays(data=[1, 0, 0, 1, 0, 1, 0])
210
+ ```
211
+
212
+ ### `BitList`
213
+
214
+ A variable number of bits up to a limit.
215
+
216
+ ```python
217
+ class Answers(BitList):
218
+ LIMIT = 20
219
+
220
+ Answers(data=[1, 0, 1])
221
+ ```
222
+
223
+ ### `ProgressiveList`
224
+
225
+ A variable number of elements with no limit.
226
+
227
+ ```python
228
+ class Temperatures(ProgressiveList[Uint16]):
229
+ pass
230
+
231
+ Temperatures(data=[20, 21, 19])
232
+ ```
233
+
234
+ ### `ProgressiveBitList`
235
+
236
+ A variable number of bits with no limit.
237
+
238
+ ```python
239
+ ProgressiveBitList(data=[1, 0, 1])
240
+ ```
241
+
242
+ ### `Container`
243
+
244
+ A fixed set of named fields.
245
+
246
+ ```python
247
+ class Point(Container):
248
+ x: Uint64
249
+ y: Uint64
250
+
251
+ Point(x=1, y=2)
252
+ ```
253
+
254
+ ### `ProgressiveContainer`
255
+
256
+ Named fields that keep their positions as the set changes.
257
+
258
+ ```python
259
+ class Square(ProgressiveContainer):
260
+ ACTIVE_FIELDS = active_fields(width=3, gaps=(1,))
261
+
262
+ side: Uint16 # position 0
263
+ color: Uint8 # position 2
264
+
265
+ Square(side=0x1234, color=0x42)
266
+ ```
267
+
268
+ ### `CompatibleUnion`
269
+
270
+ A choice between options that share one tree shape.
271
+
272
+ ```python
273
+ class Shape(CompatibleUnion):
274
+ OPTIONS = {1: Square, 2: Circle}
275
+
276
+ Shape(selector=1, data=Square(side=0x1234, color=0x42))
277
+ ```