Context
Block production (`Store.produce_block_with_signatures`) verifies that the requesting validator is the legitimate proposer for the current slot. The proposer is determined by round-robin: `proposer_index = slot % num_validators`.
If a non-proposer validator attempts to produce a block, the method must reject it with an assertion error. This prevents unauthorized block production.
No spec test filler currently tests this rejection.
What to test
Write a fork choice filler that:
- Builds a chain to slot N
- Attempts to produce a block at slot N+1 with a validator who is NOT the proposer
- Verifies the step fails with the expected error
Key assertions
- The step is `valid=False`
- The error relates to proposer authorization
- With 4 validators: slot 1 -> validator 1, slot 2 -> validator 2, slot 3 -> validator 3, slot 4 -> validator 0
Where to add the test
Add to: `tests/consensus/devnet/fc/test_block_production.py`
Code skeleton
def test_produce_block_rejects_unauthorized_proposer(
fork_choice_test: ForkChoiceTestFiller,
) -> None:
"""Block production fails when the validator is not the proposer for the slot."""
fork_choice_test(
steps=[
BlockStep(block=BlockSpec(slot=Slot(1), label="block_1")),
# Slot 2: proposer is validator 2 (= 2 % 4)
# Try to produce with validator 0 (wrong proposer)
BlockStep(
block=BlockSpec(
slot=Slot(2),
proposer_index=ValidatorIndex(0), # Wrong! Should be 2
),
valid=False,
expected_error="proposer", # Expected error substring
),
],
)
How to run
uv run fill --fork=devnet --clean -n auto -k test_produce_block_rejects
References
- `Store.produce_block_with_signatures`: `src/lean_spec/subspecs/forkchoice/store.py`
- `Validator.is_proposer_for`: `src/lean_spec/subspecs/containers/validator.py`
- Existing invalid proposer test: `tests/consensus/devnet/state_transition/test_block_processing.py::test_block_with_invalid_proposer`
Context
Block production (`Store.produce_block_with_signatures`) verifies that the requesting validator is the legitimate proposer for the current slot. The proposer is determined by round-robin: `proposer_index = slot % num_validators`.
If a non-proposer validator attempts to produce a block, the method must reject it with an assertion error. This prevents unauthorized block production.
No spec test filler currently tests this rejection.
What to test
Write a fork choice filler that:
Key assertions
Where to add the test
Add to: `tests/consensus/devnet/fc/test_block_production.py`
Code skeleton
How to run
References