Skip to content

refactor(forks): add Spec delegator surface (Stage 4A of #686)#702

Merged
tcoratger merged 3 commits into
leanEthereum:mainfrom
tcoratger:refactor/spec-delegators-stage4a
May 2, 2026
Merged

refactor(forks): add Spec delegator surface (Stage 4A of #686)#702
tcoratger merged 3 commits into
leanEthereum:mainfrom
tcoratger:refactor/spec-delegators-stage4a

Conversation

@tcoratger
Copy link
Copy Markdown
Collaborator

Summary

Stage 4A of the multi-fork architecture refactor (#686): add the spec-class method surface that mirrors the existing container methods one-for-one. The surface is added as pure delegators — bodies stay on the containers, call sites are unchanged. Stage 4B will rewrite call sites to go through the spec; Stage 4C will move the bodies in.

The new LstarSpec methods:

Domain Methods
State transition state_transition, process_slots, process_block, process_block_header, process_attestations, build_block
Forkchoice on_block, on_tick, on_gossip_attestation, on_gossip_aggregated_attestation, produce_attestation_data, produce_block_with_signatures, get_proposal_head
Block signatures verify_signatures

Each delegator is a one-line forwarder to the existing State / Store / SignedBlock method.

Why concrete on LstarSpec (not abstract on ForkProtocol)

Following Vision B (the chosen direction in #686): the architecture's central use case is "Devnet5 inherits from Devnet4 and overrides one attribute". Concrete delegators on LstarSpec propagate naturally through subclass inheritance — Devnet5Spec(LstarSpec) gets all of these for free until it needs to override one.

Adding abstract declarations on ForkProtocol would force every fork class to redeclare all delegators and would clash with the structural-protocol parameter types (which don't expose container methods like state.process_block). It is also premature without a second fork to validate the contract.

Tests

tests/lean_spec/forks/test_lstar_spec_delegators.py adds 14 tests using unittest.mock.patch.object to verify each delegator:

  • forwards its arguments to the container method unchanged, and
  • returns the container method's result verbatim.

The mock pattern proves delegation precisely without depending on the underlying container behaviour — which is exactly what Stage 4A is about.

Test plan

  • uvx tox -e all-checks (ruff check + format + ty + codespell + mdformat) green.
  • uv run pytest tests/lean_spec/forks/ — 32 fork tests pass (18 existing + 14 new).
  • uv run pytest tests/lean_spec/ — 3276 unit tests pass.

🤖 Generated with Claude Code

tcoratger and others added 3 commits May 2, 2026 23:22
…#686)

Adds the LstarSpec method surface that mirrors the existing
State / Store / SignedBlock methods one-for-one:

- State transition: state_transition, process_slots, process_block,
  process_block_header, process_attestations, build_block.
- Forkchoice: on_block, on_tick, on_gossip_attestation,
  on_gossip_aggregated_attestation, produce_attestation_data,
  produce_block_with_signatures, get_proposal_head.
- Block signatures: verify_signatures.

Each method is a pure delegator to the corresponding container method.
No call sites change — the new surface is unused initially. Stage 4B
will rewrite call sites to go through the spec; Stage 4C will move
the bodies in and replace literal Block/State/Store references with
self.*_class(...).

Tests use unittest.mock.patch.object to verify each delegator
forwards its arguments unchanged and returns the container method's
result verbatim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite the per-method docstrings on the fork-class delegators and
the delegator test suite to follow the project documentation rules:

- Each docstring describes the operation in plain English.
- No explicit class or method names that rot when renamed.
- No issue/stage references that belong in the PR description.
- No banner-style separator comments inside the class body.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extend ForkProtocol with class pointers for the inner container types
(BlockBody, BlockHeader, AggregatedAttestations, AttestationSignatures)
and the matching structural protocols. Hook them up on LstarSpec.

This is the scaffolding the next stages of leanEthereum#686 need so that moving
container method bodies into the spec can replace literal Block(...),
BlockBody(...), AggregatedAttestations(...) constructors with
self.<name>_class(...) — keeping inheriting forks free to swap any
single inner type without re-implementing the parent's logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit 250e28a into leanEthereum:main May 2, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant