Skip to content

test(fc): produce block includes pending attestations #563

@tcoratger

Description

@tcoratger

Context

When a validator is the proposer for a slot, it calls `Store.produce_block_with_signatures` to build a block. This method gathers pending attestations from the store (both gossip signatures and aggregated proofs) and includes them in the block body.

The block building process (`State.build_block`) filters attestations for validity:

  • Source must match the current justified checkpoint
  • Target root must exist in historical block hashes
  • Target slot must be justifiable after the finalized slot

No spec test filler currently tests block production end-to-end. The existing fillers use `BlockSpec` which auto-fills attestations, but don't test the `produce_block_with_signatures` path where the store selects which attestations to include.

What to test

Write a fork choice filler that:

  1. Builds a short chain
  2. Gossips attestations from multiple validators (via `AttestationStep`)
  3. Ticks to the proposal interval of the next slot
  4. Produces a block (via `BlockStep`) and verifies the block contains the expected attestations
  5. Uses `StoreChecks(block_attestation_count=..., block_attestations=[...])` to verify attestation content

Key assertions

  • The produced block includes attestations from the gossip phase
  • `block_attestation_count` matches the number of distinct `AttestationData` entries
  • `block_attestations` checks verify the correct participants and target slots

Where to add the test

Create a new file: `tests/consensus/devnet/fc/test_block_production.py`

Code skeleton

"""Block production tests."""

from consensus_testing import (
    AggregatedAttestationCheck,
    AttestationStep,
    BlockSpec,
    BlockStep,
    ForkChoiceTestFiller,
    GossipAttestationSpec,
    StoreChecks,
)
from lean_spec.subspecs.containers.slot import Slot
from lean_spec.subspecs.containers.validator import ValidatorIndex


def test_produce_block_includes_pending_attestations(
    fork_choice_test: ForkChoiceTestFiller,
) -> None:
    """Block production includes attestations accumulated via gossip."""
    fork_choice_test(
        steps=[
            BlockStep(block=BlockSpec(slot=Slot(1), label="block_1")),
            BlockStep(block=BlockSpec(slot=Slot(2), label="block_2")),
            # Gossip attestations from validators 1 and 2
            AttestationStep(
                attestation=GossipAttestationSpec(
                    validator_id=ValidatorIndex(1),
                    slot=Slot(2),
                    target_slot=Slot(2),
                    target_root_label="block_2",
                ),
            ),
            AttestationStep(
                attestation=GossipAttestationSpec(
                    validator_id=ValidatorIndex(2),
                    slot=Slot(2),
                    target_slot=Slot(2),
                    target_root_label="block_2",
                ),
            ),
            # Next block should include these attestations
            BlockStep(
                block=BlockSpec(slot=Slot(3), label="block_3"),
                checks=StoreChecks(
                    head_slot=Slot(3),
                    block_attestation_count=1,  # One AttestationData
                    block_attestations=[
                        AggregatedAttestationCheck(
                            participants={1, 2},
                            target_slot=Slot(2),
                        ),
                    ],
                ),
            ),
        ],
    )

How to run

uv run fill --fork=devnet --clean -n auto -k test_produce_block_includes

References

  • `Store.produce_block_with_signatures`: `src/lean_spec/subspecs/forkchoice/store.py`
  • `State.build_block`: `src/lean_spec/subspecs/containers/state/state.py`
  • `AggregatedAttestationCheck`: `packages/testing/src/consensus_testing/test_types/store_checks.py`
  • Existing signature aggregation fillers for patterns: `tests/consensus/devnet/fc/test_signature_aggregation.py`

Metadata

Metadata

Assignees

Labels

good first issueGood for newcomerstestsScope: Changes to the spec tests

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions