Skip to content

test(fc): produce block enforces MAX_ATTESTATIONS_DATA limit (#565)#613

Merged
tcoratger merged 2 commits intoleanEthereum:mainfrom
0xAysh:test/fc-block-production-max-attestations-data
Apr 15, 2026
Merged

test(fc): produce block enforces MAX_ATTESTATIONS_DATA limit (#565)#613
tcoratger merged 2 commits intoleanEthereum:mainfrom
0xAysh:test/fc-block-production-max-attestations-data

Conversation

@0xAysh
Copy link
Copy Markdown
Contributor

@0xAysh 0xAysh commented Apr 15, 2026

🗒️ Description

This PR adds a fork choice filler test that verifies the block builder caps the number of distinct attestation data entries at MAX_ATTESTATIONS_DATA = 16 when more than 16 are available in the store.

What the test does

  1. Builds a chain of 17 blocks (slots 1–17), each labeled so they can be referenced as attestation targets. This gives 17 blocks with distinct roots.

  2. Ticks to 70s (slot 17, interval 2 — the aggregate interval) while the gossip pool is empty. This fires the aggregate() step as a no-op, which is important: if we gossip attestations before this interval fires, aggregate() will drop them from the new pool (it only keeps proofs it creates itself, not pre-existing ones).

  3. Gossips 17 aggregated attestations, each targeting a different block (blocks 1–17). All share the same attestation slot (18), validators {0, 1, 2}, and source (the genesis justified checkpoint). Because each attestation has a different target checkpoint, they are 17 distinct AttestationData entries in the store.

  4. Ticks to 72s (slot 18 start). This passes through slot 17, interval 4 — the acceptance interval — which calls accept_new_attestations() and moves all 17 gossip payloads from the "new" pool to the "known" pool. The block builder reads from the known pool.

  5. Produces a block at slot 18 and asserts block_attestation_count=16. The block builder iterates through the 17 entries sorted by target.slot. After processing 16 entries (blocks 1–16), the count reaches MAX_ATTESTATIONS_DATA, and the builder breaks — excluding the entry targeting block 17.

Why the timing matters

The gossip aggregated attestations are stored in the "new" pool. There are two pool-related events in the interval system per slot:

  • Interval 2aggregate() fires. This replaces the new pool with only freshly created proofs. A pre-existing lone proof in the new pool (like our gossip attestation) gets dropped because there is nothing to combine it with.
  • Interval 4accept_new_attestations() fires. This migrates everything in the new pool to the known pool.

To avoid the drop at interval 2, the attestations must arrive after that interval fires. To get them into the known pool before the block is built, the tick to slot 18 must pass through interval 4 first. This is the same pattern used in the existing test_produce_block_includes_pending_attestations test.

What this correctly tests

The spec requires that a block can include at most 16 distinct AttestationData entries. This test:

  • Puts exactly 17 entries into the store (one more than the limit).
  • Lets the block builder run its normal selection path.
  • Confirms the output block has exactly 16 entries — no more, no less.

This catches any regression where the limit is removed, raised, or the break condition in the builder loop is broken.

🔗 Related Issues or PRs

Closes #565

✅ Checklist

  • Ran tox checks to avoid unnecessary CI fails:
    uvx tox
  • Considered adding appropriate tests for the changes.
  • Considered updating the online docs in the ./docs/ directory.

@0xAysh 0xAysh marked this pull request as draft April 15, 2026 01:51
@0xAysh 0xAysh force-pushed the test/fc-block-production-max-attestations-data branch from 7a4983c to 989b9f3 Compare April 15, 2026 01:53
@0xAysh 0xAysh marked this pull request as ready for review April 15, 2026 02:00
@0xAysh 0xAysh marked this pull request as draft April 15, 2026 05:01
@0xAysh 0xAysh marked this pull request as ready for review April 15, 2026 06:19
@tcoratger tcoratger force-pushed the test/fc-block-production-max-attestations-data branch from 70932e9 to 60cc434 Compare April 15, 2026 15:14
…ereum#565)

Adds a fork choice filler that verifies the block builder caps distinct
AttestationData entries at MAX_ATTESTATIONS_DATA when more are available.

All values (chain length, tick times, expected count) are derived from
protocol constants so the test adapts automatically if they change.

Also cleans up API server test teardown to use aclose() consistently,
removing redundant stop() + sleep() calls across all test classes.

Co-Authored-By: Ayush Rangrej <rangrejayush4@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger force-pushed the test/fc-block-production-max-attestations-data branch from 60cc434 to 08fd174 Compare April 15, 2026 15:23
@0xAysh
Copy link
Copy Markdown
Contributor Author

0xAysh commented Apr 15, 2026

@tcoratger Fix for the CI error, removes expected_attestations and block_attestations= from the StoreChecks. The validator-based matching in _validate_block_attestations can't disambiguate entries with identical participants. I had this error before but it might have come back when you squashed all the commits.

@tcoratger tcoratger merged commit 3ca8b81 into leanEthereum:main Apr 15, 2026
13 checks passed
@0xAysh 0xAysh deleted the test/fc-block-production-max-attestations-data branch April 15, 2026 20:04
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.

test(fc): produce block enforces MAX_ATTESTATIONS_DATA limit

2 participants