# grandine-7688-limits

## Verdict: CONFIRMED

At the supplied Grandine pin, the Gloas envelope gossip path has no CL check for builder request counts, the Beacon API's default gossip-only path publishes a block with five payload attestations before full processing rejects it, and the Engine bridge narrows validator deposits to 8,192 despite the scheduled specs allowing more. EIP-8282 makes the C2 over-limit counts impossible in a valid EL payload, and later state transition prevents an invalid child block from entering the head; neither fact supplies the missing gossip check. C3 reaches peers but not the consensus head. C4 is a conditional valid-block rejection requiring an unusually high block gas limit.

## Strongest refutation attempts

1. **Same-path checks.** The Gloas gossip spec explicitly requires `verify_execution_requests_limits` on an envelope and `verify_block_body_operation_limits` on a block. Grandine’s envelope gossip precheck only tests timing/finality/duplicates; its stateful path checks the request root and passes the requests to the EL, but no CL request-count check appears there. `process_block_for_gossip` checks the header and proposer signature; the full transition later checks operation counts. The API calls the gossip path before its full-validation path. The Engine `RawExecutionRequests` bound is a separate narrowing failure, not a conforming alternative check. [Gloas envelope gossip rules](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/p2p-interface.md#L729-L793), [block gossip rules](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/p2p-interface.md#L432-L484), [Grandine envelope path](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3662-L3692), [stateful envelope checks and EL notification](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3817-L3891), [gossip-only block check](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs#L110-L128), [full operation-count checks](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs#L864-L895).

2. **Can the conditions occur on a valid chain?** EIP-8282, scheduled by Glamsterdam’s meta EIP, caps the builder-deposit and builder-exit contracts at 64 and 16 records drained per block. Therefore C2’s 65/17 request sets cannot come from a valid EL payload. That narrows its impact, but does not refute the gossip-path divergence: a builder-signed malformed envelope can still be submitted as gossip, and Grandine calls `notify_new_payload(..., None)` then returns `Accept` without waiting for a status callback. Its mutator applies accepted envelopes and updates fork choice; it does not establish that an invalid child can become head. Full processing rejects a child carrying over-limit builder requests. [EIP-8282 limits and drain rule](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8282.md#L34-L38), [Grandine Engine notification](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3881-L3891), [acceptance and fork-choice update](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_control/src/mutator.rs#L3493-L3527), [later transition rejects builder counts](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs#L710-L732). C3’s five-attestation block is rejected by the same later transition check, but only after the API gossip route broadcasts it. C4’s validator deposits are different: they have no corresponding count cap in the scheduled rules.

3. **Spec interpretation.** Gloas defines `DepositRequests` as a `ProgressiveList`; its request-limit function checks withdrawals, consolidations, builder deposits, and builder exits, not validator deposits. Grandine’s transition code even comments that deposits intentionally have no spec limit. EIP-6110 says the deposit list “is unbounded” and the Amsterdam execution spec appends parsed deposit logs without a count check. EIP-8254 would impose the proposed 8,192 EL cap, but it is **Draft** and absent from EIP-7773’s scheduled Glamsterdam list. Thus 8,193 is within Grandine’s 65,536 Gloas implementation bound and is not prohibited by the supplied fork specs. [Gloas `DepositRequests`](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md#L261-L268), [Gloas operation limits](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md#L571-L582), [EIP-6110 unbounded-list rationale](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-6110.md#L154-L156), [Amsterdam request extraction](https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/fork.py#L800-L818), [EIP-8254 status and proposal](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8254.md#L1-L20), [Glamsterdam scheduled list](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7773.md#L18-L36), [Grandine Gloas bound](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/preset.rs#L401-L408).

4. **Later fixes.** The requested GitHub commits API endpoint was inaccessible in this browser, so I could not audit the full per-file commit history. A raw `develop` spot-check still finds no `verify_execution_requests_limits` in `fork_choice_store/src/store.rs`; the block processing still has the payload-attestation count check, the API still broadcasts on the Gossip route, and `execution_engine/src/types.rs` still narrows Gloas deposits into `MaxDepositRequestsPerPayload`. Merged PR [#997](https://github.com/grandinetech/grandine/pull/997) bumps `eth2_libp2p` and backports networking changes, including EIP-7688 work, but the current raw store path retains the omission. Merged PR [#968](https://github.com/grandinetech/grandine/pull/968) fixes serialization of pending lists on beacon-state endpoints; it does not remove the Engine request-list narrowing. [Current `develop` store](https://raw.githubusercontent.com/grandinetech/grandine/develop/fork_choice_store/src/store.rs), [current `develop` block processing](https://raw.githubusercontent.com/grandinetech/grandine/develop/transition_functions/src/gloas/block_processing.rs), [current `develop` API](https://raw.githubusercontent.com/grandinetech/grandine/develop/http_api/src/standard.rs), [current `develop` Engine types](https://raw.githubusercontent.com/grandinetech/grandine/develop/execution_engine/src/types.rs).

5. **C4 gas / reachability.** EIP-6110 gives 15,650 gas for the cheapest deposit-contract execution, plus 6,900 for a value-transferring `CALL`: `(15,650 + 6,900) × 8,193 = 184,752,150 gas` as a lower-bound estimate. It says batch deposits add about 1,000 gas per deposit amortized, giving `(15,650 + 6,900 + 1,000) × 8,193 = 192,945,150 gas`, before transaction overhead and later gas repricing. EIP-8254’s draft reports batching roughly 410 deposits per 10M gas and an empirical threshold around 193–200M gas for 8,193; this is the best fork-context reachability estimate, not a protocol constant. EIP-7825’s 2²⁴ (16,777,216) per-transaction execution-gas cap, which EIP-8037 applies to the execution dimension, does not prevent accumulation across transactions: 12 transactions at the cap total 201,326,592 gas, and the draft’s 410-per-10M batching corresponds to about 20 transactions. A 150M reference block limit would be short; a block limit around 200M makes the condition reachable. EIP-8037 does not set a hard maximum block gas limit. [EIP-6110 gas analysis](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-6110.md#L171-L173), [EIP-8254 batching estimate](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8254.md#L17-L22), [EIP-7825 transaction cap](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7825.md#L11-L30), [EIP-8037 gas dimensions and block accounting](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8037.md#L52-L63).

## Corrected records at the supplied pins

### C2 — envelope request counts

- **Spec:** The gossip function says request counts “are within their limits” and calls `verify_execution_requests_limits(envelope.execution_requests)`; the helper rejects builder deposits above 64 and builder exits above 16. [Spec lines 463–484 and 778–782](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/p2p-interface.md#L463-L484).
- **Grandine at `52cd677`:** [`fork_choice_store/src/store.rs#L3662-L3692`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3662-L3692) has only timing/finality/duplicate envelope gossip checks. [`#L3817-L3824`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3817-L3824) checks the request root; [`#L3881-L3891`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs#L3881-L3891) passes the full list to the EL and returns `Accept`, with no synchronous CL count rejection.
- **Condition / later guard:** a signed envelope carrying 17 exits or 65 builder deposits. Such counts cannot be generated by a valid EIP-8282 EL payload, and a later child block is rejected by the Gloas state transition. The missing gossip check nevertheless accepts a malformed envelope before the EL status callback; no consensus-head effect is established.
- **Other client:** Nimbus is the comparison supplied in the task (`0abc0dd0`, `gossip_validation.nim` lines 909–917 and 608–641). The specified raw file URL returned 404 in this review, so that comparison could not be independently verified.
- **Confidence / severity:** High for the missing Grandine count check; medium for peer-visible impact because the execution engine can later invalidate the payload. Severity: **invalid block accepted** (closest listed class; the object is an envelope, not a beacon block), with no head divergence demonstrated.

### C3 — API gossip-only publication

- **Spec:** Five payload attestations exceed `MAX_PAYLOAD_ATTESTATIONS = 4`, so block gossip must reject. The Beacon API says `gossip` is the default and permits broadcasting before full integration only after the requested validation succeeds. [Gloas limits](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md#L571-L582), [API v2 validation/broadcast rules](https://raw.githubusercontent.com/ethereum/beacon-APIs/master/apis/beacon/blocks/blocks.v2.yaml#L6-L33).
- **Grandine at `52cd677`:** `BroadcastValidation` defaults to `Gossip` ([`http_api/src/misc.rs#L678-L685`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/http_api/src/misc.rs#L678-L685)). [`transition_functions/src/gloas/block_processing.rs#L110-L128`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs#L110-L128) performs header/proposer-signature checks only. The v2 publication helper sends the block gossip event and network publication after that check ([`http_api/src/standard.rs#L4701-L4735`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/http_api/src/standard.rs#L4701-L4735)); full transition later rejects count >4 ([`block_processing.rs#L891-L895`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs#L891-L895)).
- **Condition / effect:** API publication of a signed block with five payload attestations and default/omitted `broadcast_validation`. Grandine publishes it, then full processing rejects it; peers can receive it, but it does not enter the head through this path.
- **Other client:** Nimbus is the supplied comparator for enforcing the spec gossip checks; its raw source fetch returned 404 as noted under C2. The Gloas spec itself is independently confirmed.
- **Confidence / severity:** High. Severity: **invalid block accepted** (broadcast to peers; not integrated into head).

### C4 — validator deposit request narrowing

- **Spec:** Validator `DepositRequests` are progressive; Gloas operation checks intentionally omit them, and EIP-6110 says their list is unbounded. The EIP-8254 8,192 limit is only Draft and not scheduled. [Gloas type and limits](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md#L261-L268), [Gloas parent-request count assertions](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md#L1654-L1695), [EIP-6110](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-6110.md#L154-L156), [meta EIP](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7773.md#L18-L36).
- **Grandine at `52cd677`:** Gloas `ExecutionRequests.deposits` is a `ProgressiveList` ([`types/src/gloas/containers.rs#L275-L287`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/gloas/containers.rs#L275-L287)); the preset allows 65,536 ([`types/src/preset.rs#L401-L408`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/preset.rs#L401-L408)). But `RawExecutionRequests` uses `ContiguousList<DepositRequest, MaxDepositRequestsPerPayload>` ([`execution_engine/src/types.rs#L1021-L1027`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/execution_engine/src/types.rs#L1021-L1027)); the preset sets that older limit to 8,192 ([`types/src/preset.rs#L386-L391`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/preset.rs#L386-L391)). The Gloas-to-Engine conversion calls `narrow_list` ([`execution_engine/src/types.rs#L1257-L1305`](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/execution_engine/src/types.rs#L1257-L1305)), which errors when the bound is exceeded.
- **Condition / effect:** a legal payload with 8,193 validator deposit logs/request entries. It fits the Gloas bound and no scheduled EL rule caps it, but Grandine’s Engine bridge cannot convert the list and rejects/fails to exchange the valid payload.
- **Other client:** no other client’s Engine bridge was independently checked in this item. Nimbus’s supplied gossip source is not an Engine-bridge comparator; that limitation is explicit rather than inferred.
- **Confidence / severity:** High for the checked conversion failure; Medium for reachability, requiring roughly a 193–200M-gas block and batched deposits. Severity: **valid block rejected**.

## Known checks and public test results

- Grandine [#918](https://github.com/grandinetech/grandine/issues/918) is **open**: generic risk from unbounded progressive containers and untrusted large network data; it does not identify these count checks or the Engine narrowing. [#997](https://github.com/grandinetech/grandine/pull/997) is **merged** (eth2_libp2p/network backports); [#968](https://github.com/grandinetech/grandine/pull/968) is **merged** (pending-list serialization on state endpoints). Neither fixes the inspected current `develop` paths.
- Public EEST material includes Glamsterdam/Amsterdam `tests@v21.0.0` and follow-up releases, but I found no candidate-specific result for five payload attestations, over-limit envelope gossip, or 8,193 validator deposits. The reviewed release notes describe execution tests and do not establish these Grandine CL outcomes. No candidate-specific public Hive result was found in the pages reviewed. No tests were run and no node or live network was contacted.

## URLs read

- Specs: [EIP-7773 meta EIP](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7773.md), [EIP-7688](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7688.md), [EIP-6110](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-6110.md), [EIP-8282](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8282.md), [EIP-8254](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8254.md), [EIP-7825](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-7825.md), [EIP-8037](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8037.md), [EIP-8038](https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8038.md), [Amsterdam execution spec](https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/fork.py), [Gloas beacon-chain spec](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/beacon-chain.md), [Gloas p2p spec](https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa8/specs/gloas/p2p-interface.md), [Beacon API blocks.v2](https://raw.githubusercontent.com/ethereum/beacon-APIs/master/apis/beacon/blocks/blocks.v2.yaml).
- Grandine pinned files: [store.rs](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_store/src/store.rs), [block_processing.rs](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/transition_functions/src/gloas/block_processing.rs), [standard.rs](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/http_api/src/standard.rs), [misc.rs](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/http_api/src/misc.rs), [Engine types](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/execution_engine/src/types.rs), [Gloas containers](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/gloas/containers.rs), [preset](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/types/src/preset.rs), [mutator.rs](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/fork_choice_control/src/mutator.rs), [Engine interface](https://raw.githubusercontent.com/grandinetech/grandine/52cd677117b5d93bf477fe4843148070b0303444/execution_engine/src/execution_engine.rs).
- Issue/PR and test references: [Grandine #918](https://github.com/grandinetech/grandine/issues/918), [#997](https://github.com/grandinetech/grandine/pull/997), [#968](https://github.com/grandinetech/grandine/pull/968), [EEST releases](https://github.com/ethereum/execution-specs/releases), [EEST Glamsterdam test milestone](https://github.com/ethereum/execution-specs/milestone/42), [Hive repository](https://github.com/ethereum/hive). The supplied Nimbus raw path [gossip_validation.nim at `0abc0dd0`](https://raw.githubusercontent.com/status-im/nimbus-eth2/0abc0dd0/beacon_chain/consensus_object_pools/gossip_validation.nim) returned 404, so its contents were not relied on.
