Versioning - #103
Conversation
- `definitions-latest.json` will now contain only the downloaded data - `definitions-latest-metadata-v1.json` will contain the metadata for version 1; later on, this will be extended by `-v2.json` file
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR introduces explicit definitions format versioning (separating the previous trzd1 “magic” into magic=trzd + version=1) and splits version-specific metadata out of definitions-latest.json into per-version metadata files, preparing the repo to generate/sign multiple versions in parallel during a transition period.
Changes:
- Split coin data (
definitions-latest.json) from per-version metadata (definitions-latest-metadata-v<version>.json) and update load/store/sign flows accordingly. - Thread a
versionparameter through serialization/merkle-root computation and CLI commands (generate,sign,computed-merkle-root,current-merkle-root). - Add/adjust tests to validate version handling and the new metadata storage layout.
File summaries
| File | Description |
|---|---|
| README.md | Updates signing/docs to reflect per-version metadata files. |
| do_sign.sh | Stages metadata file alongside definitions-latest.json after signing. |
| cli.py | Adds --version options and updates merkle-root commands for versioned metadata. |
| definitions/common.py | Implements version helpers, new metadata pathing, updated load/store APIs, and versioned payload encoding. |
| definitions/serialize.py | Threads version into merkle-root computation and serialization dispatch; adds version to metadata. |
| definitions/generate.py | Adds --version support and propagates version into serialization and output naming. |
| definitions/sign.py | Adds --version support and writes signatures into per-version metadata files. |
| definitions/download.py | Stores coin data once and writes per-version metadata for active versions. |
| definitions/ethereum/load.py | Stores coin data once and writes per-version metadata for active versions when updating display formats. |
| definitions/ethereum/serialize.py | Propagates version into payload encoding for Ethereum definitions. |
| definitions/solana/serialize.py | Propagates version into payload encoding for Solana token definitions. |
| definitions/test_common.py | New tests covering version validation, metadata pathing, and load/store roundtrips. |
| definitions/ethereum/test_load.py | Updates tests to reflect split metadata storage and versioned metadata generation. |
| definitions/ethereum/test_erc7730.py | Updates serialization callsites to include the new version parameter. |
| definitions-latest_testing.json | Test snapshot data included/updated in PR. |
Review details
Suppressed comments (1)
definitions/ethereum/load.py:486
- Same as
download.py: when multipleACTIVE_VERSIONSare enabled, callingmake_metadata()separately per version without a sharednowcan produce different timestamps/merkle roots for the same definitions snapshot. Reuse a singlenowfor the entire loop.
store_definitions_data(definitions_data)
for version in ACTIVE_VERSIONS:
metadata = make_metadata(definitions_data, version=version)
store_metadata(metadata)
- Files reviewed: 15/15 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| meta_path = metadata_path(version) | ||
| if not meta_path.is_file(): | ||
| raise click.ClickException( | ||
| f'File "{meta_path}" with definitions metadata does not exist.' | ||
| ) |
There was a problem hiding this comment.
Maybe it's easier to keep the metadata in the original JSON?
For example, we can add a new "metadata_v2" key - so there will be only one file to work with.
There was a problem hiding this comment.
Let's keep it separated - #103 (comment).
Please make sure the data & metadata files are read/written in a consistent way
(following #103 (comment) above).
| # save results: coin sections once, per-version metadata for all active versions | ||
| store_definitions_data(definitions_data) | ||
| for version in ACTIVE_VERSIONS: | ||
| metadata = make_metadata(definitions_data, version=version) | ||
| store_metadata(metadata) |
| MERKLE_ROOT=$(python cli.py current-merkle-root) | ||
|
|
||
| python cli.py sign --verify "$1" | ||
| git add definitions-latest.json | ||
| git add definitions-latest.json definitions-latest-metadata-v1.json | ||
| git commit -m "Sign definitions for $MERKLE_ROOT" |
| - the results should look something like this signing commit - https://github.com/trezor/definitions/commit/42d3093e83c85dade59af92a37fb3c33d3b047eb | ||
| - `definitions.tar.gz` file should also be created, containing signed definitions, ready for deployment | ||
|
|
||
| Metadata (merkle root, signature, format version) are version-specific and live in `definitions-latest-metadata-v<version>.json`, separate from the coin data in `definitions-latest.json`. |
| "metadata": { | ||
| "commit_hash": "6c841b35854e24d099c92c5aca7eef2942ac3d2f", | ||
| "datetime": "2026-08-13T09:49:20.206215+00:00", | ||
| "merkle_root": "5f87d66a253c555716e922f25a9691e20d836c22e493ec40e774fdbdfe686f47", | ||
| "unix_timestamp": 1786614560 | ||
| }, |
| meta_path = metadata_path(version) | ||
| if not meta_path.is_file(): | ||
| raise click.ClickException( | ||
| f'File "{meta_path}" with definitions metadata does not exist.' | ||
| ) |
There was a problem hiding this comment.
Maybe it's easier to keep the metadata in the original JSON?
For example, we can add a new "metadata_v2" key - so there will be only one file to work with.
| definitions_data: DefinitionsData, now: datetime.datetime | None = None | ||
| definitions_data: DefinitionsData, | ||
| now: datetime.datetime | None = None, | ||
| version: int = 1, |
There was a problem hiding this comment.
nit: can we drop the default value for version here?
(we already have a default in cli.py...)
There was a problem hiding this comment.
Same for other invocations of resolve_default_version().
|
Let's postpone merging it after 26.09 definitions' signatures are updated (should happen later today). |
|
@romanz Thinking of the My reasoning for splitting the files:
|
Fixes #79
Fixes #45
Fixes #100
This PR reinterprets the definitions magic
trzd1as magic+version, i.e.trzd+1.In addition, it splits
metadatafromdefintions-latest.jsoninto a separate filedefinitions-latest-metadata-v1.json. This is to prepare the repo for generating both versions at once, which will be required in the transitional period.Requires changes in
trezorlibintroduced here: trezor/trezor-firmware#7639No new functionality was introduced for version
2. As of this PR, version1remains the only one valid.