Allow for the vc to submit its proposer preferences to the network
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
Payloads from the reprocess queue should be gossiped after import if they are still timely. In devnets this happens frequently since there are many cases where the envelope arrives before the block
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
Implementation:
- payload_envelope_verification: implement the AvailabilityPending branch
in the envelope import flow. Previously returned
InternalError("Pending payload envelope not yet implemented") for any
envelope whose data columns hadn't yet been received, blocking the
end-to-end RPC import path. New `import_pending_execution_payload_envelope`
marks the payload as received in fork choice and persists the envelope to
the store; columns are still expected to arrive separately (gossip /
engineGetBlobs / reconstruction) and persist their own ops.
- sync manager: short-circuit `handle_unknown_parent_envelope` when the
parent's payload was received between gossip-verification and the trigger
reaching sync. No lookup is created; the trigger is treated as a no-op.
- gossip→sync hook: when a Gloas envelope is imported via the gossip path,
emit `SyncMessage::GossipEnvelopeImported { block_root }` so any lookups
awaiting that parent envelope unblock without depending on the in-flight
RPC response landing first. Closes the review-flagged race where a
gossip-imported envelope left child lookups pinned.
Tests (3 new):
- envelope_already_received_skips_lookup — trigger after envelope already
in fork choice creates zero lookups.
- happy_path_unknown_parent_envelope — end-to-end RPC import path: lookups
complete, head advances to the gossip block.
- happy_path_unknown_parent_envelope_via_gossip — pending envelope-only
lookup unblocked by a concurrent gossip import via the new sync hook.
Existing tests updated:
- bad_peer_envelope_rpc_failure / bad_peer_wrong_envelope_response now
expect the lookup to retry and succeed (mirroring `bad_peer_*` tests for
blocks/blobs/columns), reflecting the now-working import path.
- bad_peer_wrong_envelope_response — peer responds with a different block_root
than requested; request items raise UnrequestedBlockRoot, both lookups drop.
- crypto_on_fail_with_bad_envelope_signature — signature corruption rejected
in gossip verification, peer scored with lookup_envelope_processing_failure.
Rename the four already-landed tests to match the existing happy_path /
bad_peer / envelope_* / crypto_on_fail_with_* naming.
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.
Store gossip-verified `PayloadAttestationMessage`s in the operation pool and pack them into the block body at during block production.
Built on top of #9145.
Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
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>
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>
#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>
Serves envelope by range and by root requests. Added PayloadEnvelopeStreamer so that we dont need to alter upstream code when we introduce blinded payload envelopes.
Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com>
Add a queue that allows us to reprocess an envelope when it arrives over gossip references a unknown block root. When the block is finally imported, we immediately reprocess the queued envelope.
Note that we don't trigger a block lookup sync. Incoming attestations for this block root will already trigger a lookup for us. I think thats good enough
Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>
Which issue # does this PR address?
None
All of these are performing a check, and adding a batch, or creating a new lookup, or a new query, etc..
Hence all of these limits would be off by one.
Example:
```rust
// BACKFILL_BATCH_BUFFER_SIZE = 5
if self.batches.iter().filter(...).count() >= BACKFILL_BATCH_BUFFER_SIZE {
return None; // ← REJECT
}
// ... later adds batch via Entry::Vacant(entry).insert(...)
```
Without the `>` being changed to a `>=` , we would allow 6. The same idea applies to all changes proposed.
Co-Authored-By: Antoine James <antoine@ethereum.org>
Co-Authored-By: Jimmy Chen <jimmy@sigmaprime.io>
Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
N/A
Another find by @gitToki. Sort the preferred_ids in descending order as originally intended from the comment in the function.
Co-Authored-By: Pawan Dhananjay <pawandhananjay@gmail.com>
- Step 0 of the tree-sync roadmap https://github.com/sigp/lighthouse/issues/7678
Current lookup sync tests are written in an explicit way that assume how the internals of lookup sync work. For example the test would do:
- Emit unknown block parent message
- Expect block request for X
- Respond with successful block request
- Expect block processing request for X
- Response with successful processing request
- etc..
This is unnecessarily verbose. And it will requires a complete re-write when something changes in the internals of lookup sync (has happened a few times, mostly for deneb and fulu).
What we really want to assert is:
- WHEN: we receive an unknown block parent message
- THEN: Lookup sync can sync that block
- ASSERT: Without penalizing peers, without unnecessary retries
Keep all existing tests and add new cases but written in the new style described above. The logic to serve and respond to request is in this function `fn simulate` 2288a3aeb1/beacon_node/network/src/sync/tests/lookups.rs (L301)
- It controls peer behavior based on a `CompleteStrategy` where you can set for example "respond to BlocksByRoot requests with empty"
- It actually runs beacon processor messages running their clousures. Now sync tests actually import blocks, increasing the test coverage to the interaction of sync and the da_checker.
- To achieve the above the tests create real blocks with the test harness. To make the tests as fast as before, I disabled crypto with `TestConfig`
Along the way I found a couple bugs, which I documented on the diff.
Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com>