Conversation
🤖 Kimi Code ReviewThis PR adds SSZ consensus spec tests and improves state transition test coverage with label-based block root resolution. The changes are primarily additive and don't modify consensus logic. Issues Found: 1. Potential panics on malformed test fixtures ( Multiple
Recommendation: Convert these to 2. Redundant dependency (
3. Unused import (
Correctness Verification: The label-based root resolution in
The SSZ round-trip tests (lines 94-123) correctly verify:
Security: No vulnerabilities introduced. The Recommendation: Address the panics in test fixture parsing (Item 1) to improve debuggability when specs change or fixtures are malformed. The consensus logic additions are correct. Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
🤖 Claude Code ReviewNow I have a complete picture of the PR. Here is my review: PR #282 Review: Add SSZ Spec-Test RunnerOverviewThis PR adds a comprehensive SSZ spec-test runner ( Critical Issue
In datatest-stable = "0.3.3"appears in the [dev-dependencies]
datatest-stable = "0.3.3"The Cargo.lock confirms it was added to Moderate IssuesNon-deterministic test ordering in
Panics in fixture conversion produce poor error messages Several conversions in
For production test infrastructure these are acceptable in the short term, but they make fixture debugging painful. Minor Observations
In Label-based vs. direct checks are not mutually exclusive In Block registry includes the root of the failing block In What's Done Well
SummaryOne blocking issue: move Automated review by Claude (Anthropic) · sonnet · custom prompt |
🤖 Codex Code Review
I did not see a production consensus-logic regression in the I couldn’t run Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
Greptile SummaryThis PR adds an SSZ spec-test runner for the Confidence Score: 5/5Safe to merge — all findings are P2 style/consistency suggestions with no correctness impact on production code. The only finding is a P2 inconsistency in iteration bounds between two bitlist checks in test infrastructure; it does not affect production logic or cause data loss. All other changes (new derives, new test runners, Cargo.toml update) are clean and well-structured. crates/blockchain/state_transition/tests/stf_spectests.rs — the justified_slots vs justifications_validators iteration bound inconsistency warrants a quick look before the fixture suite grows.
|
| Filename | Overview |
|---|---|
| crates/common/types/tests/ssz_spectests.rs | New SSZ spec-test runner that validates encode/decode round-trips and hash tree roots for all consensus container types using datatest-stable. |
| crates/common/types/tests/ssz_types.rs | Fixture types for SSZ spec tests; mirrors test-fixtures crate (which can't be reused due to circular dependency) with SSZ-native boolean bitlist representation for justified_slots. |
| crates/blockchain/state_transition/tests/stf_spectests.rs | Adds compare_post_states with thorough optional field checks; minor inconsistency in iteration bounds between justified_slots and justifications_validators comparisons. |
| crates/blockchain/state_transition/tests/types.rs | New PostState struct with deny_unknown_fields and many optional fields for partial post-state assertion; well-designed for incremental fixture coverage. |
| crates/common/types/src/attestation.rs | Adds HashTreeRoot derive to SignedAttestation and SignedAggregatedAttestation, required by the new SSZ spec-test runner's run_typed_test constraint. |
| crates/common/types/Cargo.toml | Adds datatest-stable 0.3.3 as a dev-dependency and registers the new ssz_spectests integration test binary with harness = false. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[JSON fixture file] --> B[SszTestVector::from_file]
B --> C{For each test case}
C --> D{fixture_format == ssz?}
D -- No --> E[Return Err: unsupported format]
D -- Yes --> F[run_ssz_test]
F --> G{Match type_name}
G -- known type --> H[run_typed_test<F, D>]
G -- unknown type --> I[Skip with println]
H --> J[1: JSON → fixture type F → domain type D]
J --> K[2: D::to_ssz == expected_bytes?]
K -- No --> L[Return Err: encoding mismatch]
K -- Yes --> M[3: from_ssz_bytes → re-encode == expected_bytes?]
M -- No --> N[Return Err: round-trip mismatch]
M -- Yes --> O[4: hash_tree_root == expected_root?]
O -- No --> P[Return Err: root mismatch]
O -- Yes --> Q[Test passes]
Comments Outside Diff (1)
-
crates/blockchain/state_transition/tests/stf_spectests.rs, line 227-258 (link)Inconsistent iteration bounds between bitlist checks
justified_slotsiterates0..justified_slots.data.len()(expected length), giving "check only the first N bits" semantics — extra bits in the actual state are silently ignored.justifications_validatorsiterates0..post_state.justifications_validators.len()(actual state length), giving exact-equality semantics — if the state has more or fewer bits thanjustifications_validators.data, theVeclength differs and the comparison always fails even when all fixture-specified bits match.Pick one consistent strategy: for partial/prefix checking use the expected data length throughout; for exact-equality checking use the state length throughout (or add a length assertion separately). The current mismatch means the two fields will behave differently under any fixture where the lengths differ.
Prompt To Fix With AI
This is a comment left during a code review. Path: crates/blockchain/state_transition/tests/stf_spectests.rs Line: 227-258 Comment: **Inconsistent iteration bounds between bitlist checks** `justified_slots` iterates `0..justified_slots.data.len()` (expected length), giving "check only the first N bits" semantics — extra bits in the actual state are silently ignored. `justifications_validators` iterates `0..post_state.justifications_validators.len()` (actual state length), giving exact-equality semantics — if the state has more or fewer bits than `justifications_validators.data`, the `Vec` length differs and the comparison always fails even when all fixture-specified bits match. Pick one consistent strategy: for partial/prefix checking use the expected data length throughout; for exact-equality checking use the state length throughout (or add a length assertion separately). The current mismatch means the two fields will behave differently under any fixture where the lengths differ. How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: crates/blockchain/state_transition/tests/stf_spectests.rs
Line: 227-258
Comment:
**Inconsistent iteration bounds between bitlist checks**
`justified_slots` iterates `0..justified_slots.data.len()` (expected length), giving "check only the first N bits" semantics — extra bits in the actual state are silently ignored. `justifications_validators` iterates `0..post_state.justifications_validators.len()` (actual state length), giving exact-equality semantics — if the state has more or fewer bits than `justifications_validators.data`, the `Vec` length differs and the comparison always fails even when all fixture-specified bits match.
Pick one consistent strategy: for partial/prefix checking use the expected data length throughout; for exact-equality checking use the state length throughout (or add a length assertion separately). The current mismatch means the two fields will behave differently under any fixture where the lengths differ.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "test: add missing checks to STF spec-tes..." | Re-trigger Greptile
299f340 to
978fc84
Compare
This PR adds a test runner for the new SSZ spec-test format. It also adds some new post-state checks to the STF spec-test runner.