Wires the lookup test rig for Gloas:
- Capture per-block execution payload envelopes from the external harness
and serve them to peers via a new `network_envelopes_by_root` map.
- Handle `RequestType::PayloadEnvelopesByRoot` in `simulate_on_request` and
`Work::RpcPayloadEnvelope` in the simulator processor branch.
- Allow `TestRig` callers to override the genesis validator count and
bump initial balances to `max_effective_balance_electra` post-Electra,
which Gloas committee-selection requires for genesis init to converge.
Adds four tests for the parent-envelope-unknown flow (each verified
red/green by stubbing the corresponding source path):
- `creates_envelope_and_child_lookups` — `UnknownParentEnvelope` produces
exactly one envelope-only lookup for the parent root and one child
lookup awaiting that envelope.
- `idempotent_triggers` — repeated triggers for the same parent merge
into the existing envelope lookup; no duplicate lookups are created.
- `issues_payload_envelopes_by_root_rpc` — the envelope-only lookup
dispatches a `PayloadEnvelopesByRoot` RPC for the parent block_root.
- `drops_cascade_on_rpc_error` — when the envelope RPC errors, the
envelope lookup is dropped and the awaiting child cascades with it.
The end-to-end happy path (envelope arrives → child unblocks → block
imports → head advances) is gated on
`process_execution_payload_envelope` supporting `AvailabilityPending`,
which today returns `InternalError("Pending payload envelope not yet
implemented")`. That gap is independent of this PR's lookup machinery.
Replace `assert_event_journal_contains_at_least_ordered` helper with an
inline drain that just counts the gossip + reconstruction events. The
helper was carrying around `WORKER_FREED` bookkeeping and a strict
prefix-match for one caller; counting the two relevant work types until
both thresholds are met is the same check with much less code.
- block_verification: skip ParentEnvelopeUnknown check when parent is the
proto-array anchor. The anchor's `payload_received` is intentionally
false per spec (never added to `store.payloads`), but no envelope is
expected for it; without this exception the check rejects every
post-anchor gloas block.
- network tests: disable `engineGetBlobs` in the TestRig harness. Under
real crypto the mock EL's blob fetch raced the gossip path, importing
via a spawned task that the test didn't await -- leaving `head_root()`
unchanged when the assertion ran. The tests are designed to exercise
the gossip + data-column path; the engine fetch was incidental.
- network tests: relax `data_column_reconstruction_at_deadline` to allow
trailing duplicate reconstruction work items. The reprocess queue
removes its dedup entry on dispatch, so a column processed during an
in-flight reconstruction can dispatch a second one. The second is a
no-op via `reconstruction_started`, so accept >= 1 trailing event.
N/A
Do not make the AI agent always fmt and lint. This takes way too long and the agents I work with take this too literally sometimes and run lint after incomplete changes just wasting time.
I feel its not a big ask to run fmt and lint yourself and/or run it in some local configs instead of global ones.
Co-Authored-By: Pawan Dhananjay <pawandhananjay@gmail.com>
When producing a block at the fork, treat parent payload status as full
I've been testing on kurtosis and this fixes an issue where we cant propose a block at the fork.
This is a screenshot of the fix. The envelope shows missing because we are missing an SSE event, but the envelope is in fact being imported and the chain is progressing just fine
<img width="652" height="748" alt="image" src="https://github.com/user-attachments/assets/7764a68c-33fb-4987-a691-0af71f0bea02" />
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
Just a little naming cleanup (no semantic changes) to remove mentions of pending and full states that were still lurking.
This hopefully helps Claude forget about the concept (it defaults to naming variables `pending_state`s without this change).
Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
This reverts commit 2749e18d0e, from:
- #9092
We no longer need those changes since the abolition of pending/full states.
Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
Fix a vulnerability in the slasher whereby it would OOM upon processing an invalid attestation with an artificially high `validator_index`. This fix has already been made available to affected users on the `slasher-fix` branch.
- Prevent attestations from being passed to the slasher prior to signature verification. This was unnecessary, as they would later be passed on successful validation as well.
- Add a defensive cap on the maximum validator index processable by the slasher. The cap is high enough that it shouldn't be reached for several years, and will quickly result in warning logs if forgotten.
- Add a regression test that confirms that the issue is fixed.
Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
Fix a **consensus fault** in `PreEpochCache` 🙀
Fortunately it's only reachable on a network with `total_active_balance=0`, i.e. a network that's already completely dead. As such this PR is not time-sensitive in any way.
Add the floor on `total_effective_balance` when converting from `PreEpochCache` to `EpochCache`. An alternative would be to add the floor inside `PreEpochCache::get_total_active_balance`, however that would be redundant, as the only place this function is called outside this file is in single-pass epoch processing:
176cce585c/consensus/state_processing/src/per_epoch_processing/single_pass.rs (L461-L462)
The `set_total_active_balance` call already handles the floor.
A regression test is included.
Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
N/A
Adds lints for rust 1.95. Mostly cosmetic.
1. .zip(a.into_iter()) -> .zip(a) . Also a few more places where into_iter is not required
2. replace sort_by with sort_by_key
3. move if statements inside match block.
4. use checked_div instead of if statements. I think this is debatable in terms of being better, happy to remove it if others also feel its unnecessary
Co-Authored-By: Pawan Dhananjay <pawandhananjay@gmail.com>
The tracing exporter uses a `PrefixBasedSampler` that only samples root spans whose name starts with `lh_`. Rename the VC root spans to include the prefix so their traces are exported.
Thanks @lmnzx for pointing this out!
Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
New audit failure from `RUSTSEC-2026-0098`
Bump `rustls-webpki` to an unaffected version, add an ignore for the old version used by `warp` 0.3
Co-Authored-By: Mac L <mjladson@pm.me>
Co-Authored-By: Pawan Dhananjay <pawandhananjay@gmail.com>
Closes#8949
Implements peer penalties and REJECT/IGNORE message propagation for `SignedExecutionPayloadEnvelope` gossip handling, completing follow-up work from #8806.
Feedback on the error classification would be appreciated.
### Key Implementation Details
- Maps all 15 `EnvelopeError` variants to REJECT/IGNORE based on [Gloas p2p spec](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/p2p-interface.md#execution_payload)
- Follows `ExecutionPayloadError` handling pattern from block gossip (`penalize_peer()` method)
- Uses explicit variant matching (rather than catch-all `_`) for type safety
- Applies `LowToleranceError` penalty for protocol violations (invalid signatures, mismatches, etc.)
- Ignores without penalty for spec-defined cases (unknown block root, prior to finalization) and internal errors
Co-Authored-By: 0u-Y <yyw1000@naver.com>
Co-Authored-By: Eitan Seri-Levi <eserilev@gmail.com>
Gossip verify and cache bids and proposer preferences. This PR also ensures we subscribe to new fork topics one epoch early instead of two slots early. This is required for proposer preferences.
Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>
- #6689
The intention is to only modify the INFO logs that's emitted regularly to reduce the verbosity. But I understand that this change will affect other display in the logs too that uses the `ExecutionBlockHash` display. So would love some feedbacks about the change.
Co-Authored-By: Tan Chee Keong <tanck@sigmaprime.io>
Co-Authored-By: Mac L <mjladson@pm.me>
#9077
Where possible replaces all instances of `validator_monitor::timestamp_now` with `chain.slot_clock.now_duration().unwrap_or_default()`.
Where chain/slot_clock is not available, instead replace it with a convenience function `slot_clock::timestamp_now`.
Remove the `validator_monitor::timestamp_now` function.
Co-Authored-By: Mac L <mjladson@pm.me>
Addresses #5403
- Added `check_fee_recipient()` method to validate individual validators
- Added `check_all_fee_recipients()` to validate all validators on startup
- Validator client now fails to start if any enabled validator lacks a fee recipient and no global flag is used.
- Added Clear error messages to guide users on how to fix the issue
- Added unit tests
Co-Authored-By: AbolareRoheemah <roheemahabo@gmail.com>
#8926
Add a step to CI which runs `cargo check` across all combinations of features for certain crates using `cargo-hack`
Co-Authored-By: Mac L <mjladson@pm.me>