1402 Commits

Author SHA1 Message Date
terence
8b0cdc2db9 Implement defer payload processing (#16658)
**1 — proto + API structs**
New fields: `execution_requests_root` on the bid,
`parent_execution_requests`
on the body. `state_root` gone from the envelope. Nothing uses them yet.

  **2 — consensus-types accessors + state interfaces**
Wires up the Go side of (1). Also adds `QueueBuilderPaymentForSlot` and
  factors `queueBuilderPaymentAtIndex` out of `QueueBuilderPayment`.

  **3 — ProcessParentExecutionPayload + spec tests**
  New spec fn, not wired in yet. Read it side-by-side with the pyspec. 

  **4 — swap the mutation site**
Old `ProcessExecutionPayload` drops all its state mutations and becomes
  verify only. `ProcessParentExecutionPayload` gets wired into
`ProcessBlockForStateRoot` before `process_block_header` per spec order.

Also: renames `IsParentBlockFull` → `LatestBlockHashMatchesBidBlockHash`
(old name was misleading, it's just an equality check).
`ProcessSlotsForBlock`
and `head.full` are deleted. Envelope no longer computes a `state_root`.

  **5 — proposer**
Sets `parent_execution_requests` on the body, builds the bid with the
new
fields, computes withdrawals via `computePayloadWithdrawals`. That fn
has
  three branches (empty parent / pre-Gloas parent / full Gloas parent).

  **6 — gossip validation**
Adds `validateParentExecutionRequests`: body's
`parent_execution_requests`
  has to hash to what the parent bid said. 

  **7 — rip out dual-key state access**
  State's always keyed by beacon block root now, so all the "sometimes
execution block hash" code across forkchoice, stategen, and the
blockchain
  service can go. Almost pure deletions. One actual behavior change: FCU
notifications use `forkchoice.BlockHash()` instead of
`st.LatestBlockHash()`

**8 — rename ProcessExecutionPayload → VerifyExecutionPayloadEnvelope**
  Rename only, nothing else. Just approve.

  **9 — test utilities + assertions + changelog**
Mechanical. Test builders pick up the new fields, a few stray
`envelope.StateRoot` references get swept up, changelog added.
2026-04-24 19:47:38 +00:00
terence
060e4fc148 Add BAL, slot pre-compile, and engine-api implementations (#16687)
- Add EIP-7928 block access list (`ExecutionPayloadGloas` extends Deneb
with `block_access_list`) and wire up Amsterdam engine API:
`newPayloadV5`, `getPayloadV6`, `forkchoiceUpdatedV4`,
`getPayloadBodiesByHashV2`/`RangeV2`, plus
`PayloadAttributesV4` with `slotNumber` (EIP-7843). Payload
reconstruction now runs `eth_getBlockByHash` and
`getPayloadBodiesByHashV2` in parallel.
  - Move `slot` from `ExecutionPayloadEnvelope` onto the payload itself
- Swap `latest_block_hash` and `latest_execution_payload_bid` ordering
in `BeaconStateGloas`
2026-04-22 18:50:02 +00:00
satushh
cc484f8752 Cache random_bytes in compute_balance_weighted_selection (#16708)
**What type of PR is this?**

Optimisation

**What does this PR do? Why is it needed?**

Implements https://github.com/ethereum/consensus-specs/pull/5079

Performance optimisation: the PTC balance-weighted selection now
computes `hash(seed || i/16)` once per 16 rounds instead of once per
candidate.

**Which issues(s) does this PR fix?**



**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: terence <terence@prysmaticlabs.com>
2026-04-22 16:43:17 +00:00
james-prysm
9069afc6d0 Get block v4 (#16488)
**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

implements the new GET /eth/v4/validator/blocks/{slot} endpoint, we
don't hook up the validator client to use it yet for post gloas in this
pr.

**Which issues(s) does this PR fix?**

Fixes https://github.com/ethereum/beacon-APIs/pull/580

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-04-14 03:23:42 +00:00
terence
de34b4dfae Skip inclusion proof verification for Gloas data columns (#16647)
- Gloas data column sidecars don't carry block headers or inclusion
proofs
  - Skip `VerifyDataColumnSidecarInclusionProof` for Gloas sidecars
- Skip Gloas columns in the batch verifier `SidecarInclusionProven` loop
2026-04-10 15:18:48 +00:00
terence
e9fdeee7bb Add missing fields to Gloas genesis block bid (#16646)
- The Gloas genesis block's `SignedExecutionPayloadBid` was missing
`PrevRandao` (32 bytes) and `FeeRecipient` (20 bytes)
  - This caused SSZ marshaling failures at genesis
2026-04-10 14:25:44 +00:00
terence
10cd675793 Construct data column sidecars from bid in Gloas blocks (#16638)
- Add `PopulateFromBid` as a new `ConstructionPopulator` that extracts
KZG commitments directly from the execution payload bid in Gloas (ePBS)
blocks
- In Gloas, the execution payload arrives separately via the payload
envelope, but the bid's KZG commitments are available in the block
immediately — this allows data column sidecars to be constructed from
the EL (`engine_getBlobsV2`) as soon as the block arrives, without
waiting for the envelope
- Wire `PopulateFromBid` into `processSidecarsFromExecutionFromBlock`
for Gloas blocks, replacing the previous early return that skipped EL
reconstruction entirely

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-04-08 13:38:22 +00:00
terence
883d78221f Use ValidatorIndex type for proposer_lookahead in beacon state proto (#16634)
- Adds `cast_type` annotation to `proposer_lookahead` field in
`BeaconStateFulu` and `BeaconStateGloas` protobuf definitions to use
`primitives.ValidatorIndex` instead of raw `uint64`
- Matches the spec type `Vector[ValidatorIndex, ...]` and is consistent
with how `ptc_window` already uses `cast_type` for its validator indices
- Updates `InitializeProposerLookahead` to return
`[]primitives.ValidatorIndex` directly, removing all `uint64` conversion
boilerplate
- Adds `proposerLookaheadVal()` copy method for `ToProto` consistency
with other slice fields
2026-04-07 02:42:24 +00:00
Manu NALEPA
6e4d7fd781 ProcessEffectiveBalanceUpdates: Avoid copying a validator when the computed effective balance is unchanged. (#16631)
**What type of PR is this?**
Bug fix

**What does this PR do? Why is it needed?**
In (electra) `ProcessEffectiveBalanceUpdates`, a `0x00...` validator
with a balance > 33.25 ETH enters in the
```go
if balance+downwardThreshold < val.EffectiveBalance() || val.EffectiveBalance()+upwardThreshold < balance {
...
}
```

condition.

The validator is copied (`newVal = val.Copy()`) and returned, **even if
the effective balance did not actually change**.
As a consequence, this validator is considered as "dirty" in the
validators field trie, and all the corresponding branches are
re-computed when computing the hash trie root of the the validators
field trie of the beacon state.

This PR adopts the same behavior as before Electra:

6f437b561a/beacon-chain/core/electra/effective_balance_updates.go (L32-L63)

and copies/considers dirty the validator only if its effective balance
changed.

**Which issues(s) does this PR fix?**
- https://github.com/OffchainLabs/prysm/issues/16630

**Other notes for review**
The first commit only introduces a new metric showing the issue.
The second commit actually solves the issue.

**Before this PR:**
**~9.400 validators** considered as dirty on mainnet every epoch

<img width="942" height="308" alt="image"
src="https://github.com/user-attachments/assets/31da9c92-aa0f-4d71-a402-92ed62738803"
/>


**After this PR:**
**~15 validators** considered as dirty on mainnet every epoch (reduction
of ~x620).

<img width="946" height="312" alt="image"
src="https://github.com/user-attachments/assets/afc5e72a-ccda-4636-87d9-dab2fbbf5c1c"
/>


**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-04-06 16:29:31 +00:00
terence
9dba7c5319 Check pending deposits before applying builder deposits (#16532)
Add `IsPendingValidator` check to `processDepositRequest` so that
deposit requests with builder credentials are routed to the validator
pending queue when a pending deposit with a valid signature already
exists for the same pubkey

Also updated spec test to alpha3 so we can merge this with green CI/CD

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-04-02 21:23:21 +00:00
terence
c02c057b7d core: implement cached PTC window in state (#16573)
This adds the PTC cache to the Gloas proto and native beacon state,
updates SSZ/hash-tree-root handling, initializes the cache on Gloas
upgrade, rotates it during epoch processing, and switches payload
committee lookups to read from the cached window instead of recomputing
PTC assignments on demand

Reference: https://github.com/ethereum/consensus-specs/pull/4979
2026-04-02 17:56:02 +00:00
terence
b6ec6a8eec fix: add Gloas genesis block support (#16627)
## Summary

- Add missing `*ethpb.BeaconStateGloas` case to
`NewGenesisBlockForState` type switch
- Create `gloasGenesisBlock()` with the correct Gloas block body
structure (`SignedExecutionPayloadBid` + `PayloadAttestations`)

Fixes the `unknown underlying type for state.BeaconState value` error
when starting a node from a Gloas genesis state.
2026-04-02 17:05:20 +00:00
terence
3ca8c3ba35 Support gloas blob protobuf for readonly (#16618)
- Refactor `RODataColumn` to support both Fulu and Gloas data column
sidecar protobuf types. Fulu-only accessors now return errors instead of
zero values when called on Gloas sidecars
- Wire up Gloas `DataColumnSidecarGloas` across gossip topic mappings,
pubsub decoding, validation, and RPC serving
  - Gloas duplicate check uses `(block_root, index)` per spec
- Precompute and broadcast Gloas data column sidecars during block
proposal, before the execution payload envelope, so receivers pass data
availability checks
- Fix `WriteDataColumnSidecarChunk` to encode the correct SSZ type per
fork
2026-04-02 15:44:41 +00:00
terence
1092c7135f Refactor gloas process_execution_payload into distinct entry points (#16600)
## Summary

- Decompose `process_execution_payload` into four explicit entry points,
one per caller
- Extract shared helpers: `cacheLatestBlockHeaderStateRoot`,
`setLatestBlockHeaderStateRoot`, `validatePayloadConsistency`,
`verifyPostStateRoot`
- Unexport package-internal functions:
`applyExecutionPayloadStateMutations`,
`verifyExecutionPayloadEnvelopeSignature`
- Rename `ApplyBlindedExecutionPayloadEnvelopeForStateGen` →
`ProcessBlindedExecutionPayload`
- Rename `ApplyExecutionPayloadNoVerifySig` →
`ProcessExecutionPayloadWithDeferredSig`

  ## Motivation

The previous code routed all callers through `ApplyExecutionPayload`,
which tried to serve every path at once. Each caller's assumptions were
implicit rather than visible in the code. Now each entry point reads
top-to-bottom as exactly the steps that path requires.

  ## Entry points

| Step | `ProcessExecutionPayload` |
`ProcessExecutionPayloadWithDeferredSig` | `ApplyExecutionPayload` |
`ProcessBlindedExecutionPayload` |
  |---|---|---|---|---|
  | **Caller** | gossip | init-sync | proposer | stategen / replay |
| **Verify signature** |  inline | 🔶 deferred (`SignatureBatch`) |  |
 |
| **Patch header state root** | `cacheLatestBlockHeaderStateRoot`
(computes HTR) | `setLatestBlockHeaderStateRoot` (caller-provided) |
`cacheLatestBlockHeaderStateRoot` (computes HTR) |
`setLatestBlockHeaderStateRoot` (caller-provided) |
| **Validate consistency** | `validatePayloadConsistency` (full) |
`validatePayloadConsistency` (full) | `validatePayloadConsistency`
(probably can be removed but outside the scope) | minimal bid checks
(builder index + block hash) |
| **Verify post-state root** |  `verifyPostStateRoot` | 
`verifyPostStateRoot` |  (caller computes it) |  (trusted) |
| **Envelope type** | `ROSignedExecutionPayloadEnvelope` |
`ROSignedExecutionPayloadEnvelope` | `ROExecutionPayloadEnvelope` |
`ROBlindedExecutionPayloadEnvelope` |
2026-04-02 09:32:11 +00:00
Potuz
543746d95d Gloas Init sync (#16528)
From the commit comments:
   
 Fetch Payloads along side blocks on init sync

Adds envelopes to the fetchRequestResponse struct which is populated by
    a call to fetchPayloads.

When requesting block batches if the batch is across the Fulu fork it is
    truncated. For a batch that is purely Gloas it requests the
    corresponding payload envelopes by range.

The batch fetcher verifies payloads--blocks consistency, that is that
the full batch could be imported completely into the blockchain without
gaps. If both payloads and blocks are not consistent and were delivered
    by the same peer, we downscore them

    The batch fetcher verifies self-consistency of the payloads, that is
    that the payloads follow the parehthash chain. If they don't we
    downscore the peer that served them.

    It changes the signature of fetchSidecars and fetchBlocksFromPeer to
    modify the response in place.

    Filter processed blocks and payloads

Add round robin changes to the batch processors. When receiving a batch,
    we filter all blocks that were processed. Since the payload fetcher
enforces consistency with payloads, removing all payloads envelopes that
match the removed blocks also keeps a consistent batch. The only problem
may be the first payload that may be processed. The usual finalized slot
check for blocks does not necessarily work for Payloads since we may not
    have processed a payload from a finalized slot. Hence we explicitly
    check the first payload in the batch against our DB.

In addition, for the unfinalized section we do an extra check against
    forkchoice before insertion.

It modifies ReceiveBlockBatch to deal with batches with payloads. It
adds extra safety mechanisms in case the compatibility constraints from
init sync were violated.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:37:15 +00:00
Potuz
2898a5e8a2 Fix replay blocks (#16482)
This PR fixes any `StateByRoot` possible acess to return correctly the
CL post-state if a block root is asked for and the EL post-state if a
block hash is asked for.

⚠️ This fix includes logical changes on stategen's behavior for example
on `replayBlocks`. `replayBlocks` also added in the end a process slots
call to reach the requested target slot, I removed this and made it part
of the caller to decide if calling it or not. Luckily the two callsites
for this function did not need it.


Replay blocks however applies all blocks that are given passed,
including all needed execution payload envelopes between these blocks.
The function is aware and determines which execution payloads need to be
applied, even if some non-canonical ones are found on the DB. However,
the return state **is always the CL post-state** of the last applied
block. It will never apply the last payload envelope if it exist at that
height. It is the responsibility of the caller to apply this payload.
For that, the helper `applyPayloadIfNeeded` was added.

State replay assumes that the given payloads are valid, in particular it
does not perform state root computations except when processing slots.
We could avoid those computations by a simple refactoring, but I left
this for a future PR. In this PR I do save the state root computation
for payload processing and a few hashtreeroots for the corresponding
block.

The function `loadStateByRoot` is shortcircuited to give the right reply
in a fast way: if the passed root (that could be a hash or a blockroot)
is not found in any cache. Then it tries to find a block with this root,
if there is no block with that root, we assume it is a beacon block hash
and call this function again recursively with the corresponding beacon
block root. All that remains is applying the payload envelope. This way
we are certain that `StateByRoot()` returns the correct post-state if
available.

The main change is in the replayer itself to choose which order of
payloads need to be applied when doing the state transition. We rely on
process slots to deal with the state root computation for missing
payloads. Otherwise we rely on the child payload envelope to deal with
the state root computation when available. We could use the same
technique to avoid the process slots state root computation by inlining
it in the replayer, which will be the case for a future PR.


I fixed `FillInForkchoiceMissingNodes` but I *did not* fix
`onBlockBatch` to be Gloas compatible yet.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:09:19 +00:00
terence
f43ba7851c p2p: add execution payload bid gossip topic and verification (#16539)
This PR implements the `execution_payload_bid` gossip topic from the
Gloas spec. Builders broadcast signed bids for future execution
payloads, validated against proposer

- Gossip topic registration, mapping, and subscriber for
`execution_payload_bid`
- Verification: current/next slot, builder active, payment non-zero,
parent block root seen, parent block hash match, builder balance,
signature
- `HighestExecutionPayloadBidCache` keyed by (slot, parent_hash,
parent_root) with pruning
  - Per-builder seen cache for dedup
  - `BlockHash` on `ForkchoiceFetcher` interface
  - Export `ValidatePayloadBidSignature` for verifier reuse

  > **Note:** This is PR 3 of 3 in a stack. Please review in order:
  > 1. Proposer preferences P2P
  > 2. Proposer preferences RPC endpoint
  > 3. **This PR** — execution payload bid P2P
2026-03-19 21:45:39 +00:00
Manu NALEPA
65d428db58 Refactor state retrieval to use ReadOnly methods when possible, avoiding unnecessary copies. (#16511)
**What type of PR is this?**
Optimization (@nisdas)

**What does this PR do? Why is it needed?**
This PR:
- Defines a new `StateManager.StateByRootNoCopy` to retrieve a state
**without** copying it.
(This function returns a `state.ReadOnlyBeaconState` to prevent the
caller modifying it.)
- Changes the signature of functions using `state.BeaconState` to
`state.ReadOnlyBeaconState` when possible
(principle of least privilege)
- Modify the `StateManager.StateByRootIfCachedNoCopy` function to also
check in the epoch boundary cache.

> [!TIP]
> Please read commit by commit 

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-03-18 21:23:54 +00:00
satushh
93f7214b32 Voluntary exit gloas (#16527)
**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This PR implements voluntary exit specific logic for gloas builder,
specifically the following ones:

-
[get_pending_balance_to_withdraw_for_builder](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-get_pending_balance_to_withdraw_for_builder)
-
[process_voluntary_exit](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#modified-process_voluntary_exit)
-
[initiate_builder_exit](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-initiate_builder_exit)
-
[MIN_BUILDER_WITHDRAWABILITY_DELAY](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#time-parameters)

---------

Co-authored-by: Potuz <potuz@prysmaticlabs.com>
2026-03-17 15:33:09 +00:00
Manu NALEPA
1bffcc84f4 Beacon state: Replace *ethpb.Validator by CompactValidator (#16535)
**What type of PR is this?**
Optimisation (@nisdas)

**What does this PR do? Why is it needed?**
The beacon state contains the list of all validators that have been at
least once deposited on the network.

| Network  | Active       | Total                | Ratio      |
|----------|-----------|---------------|---------|
| Hoodi      | 1,224,855 | **1,294,521**  | 94.1%   |
| Mainnet  | 948,883   | **2,229,313** | 43.56% |

Currently, the validators are stored in the beacon state like this:
```go
type BeaconState struct {
...
	validatorsMultiValue                *MultiValueValidators
...
}

type MultiValueValidators = multi_value_slice.Slice[*ethpb.Validator]

type Validator struct {
	state                      protoimpl.MessageState                                            `protogen:"open.v1"`
	PublicKey                  []byte                                                            `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty" spec-name:"pubkey" ssz-size:"48"`
	WithdrawalCredentials      []byte                                                            `protobuf:"bytes,2,opt,name=withdrawal_credentials,json=withdrawalCredentials,proto3" json:"withdrawal_credentials,omitempty" ssz-size:"32"`
	EffectiveBalance           uint64                                                            `protobuf:"varint,3,opt,name=effective_balance,json=effectiveBalance,proto3" json:"effective_balance,omitempty"`
	Slashed                    bool                                                              `protobuf:"varint,4,opt,name=slashed,proto3" json:"slashed,omitempty"`
	ActivationEligibilityEpoch github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Epoch `protobuf:"varint,5,opt,name=activation_eligibility_epoch,json=activationEligibilityEpoch,proto3" json:"activation_eligibility_epoch,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Epoch"`
	ActivationEpoch            github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Epoch `protobuf:"varint,6,opt,name=activation_epoch,json=activationEpoch,proto3" json:"activation_epoch,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Epoch"`
	ExitEpoch                  github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Epoch `protobuf:"varint,7,opt,name=exit_epoch,json=exitEpoch,proto3" json:"exit_epoch,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Epoch"`
	WithdrawableEpoch          github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Epoch `protobuf:"varint,8,opt,name=withdrawable_epoch,json=withdrawableEpoch,proto3" json:"withdrawable_epoch,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Epoch"`
	unknownFields              protoimpl.UnknownFields
	sizeCache                  protoimpl.SizeCache
}
```

Some fields, used only by protobuf (`state`, `unknownFields`,
`sizeCache`) are not used by the beacon node.
Some other fields, stored as slices (`PublicKey`,
`WithdrawalCredentials`) need extra memory (`ptr+len+cap`) while they
could be stored as arrays because their sizes are fixed and known in
advance.

We define a new custom type called `CompactValidator`, which is a
fixed-size, pointer-free representation of a validator:

```go
type CompactValidator struct {
	PublicKey                  [fieldparams.BLSPubkeyLength]byte // 48 bytes
	WithdrawalCredentials      [32]byte                          // 32 bytes
	EffectiveBalance           uint64                            // 8 bytes
	Slashed                    bool                              // 1 byte
	ActivationEligibilityEpoch primitives.Epoch                  // 8 bytes
	ActivationEpoch            primitives.Epoch                  // 8 bytes
	ExitEpoch                  primitives.Epoch                  // 8 bytes
	WithdrawableEpoch          primitives.Epoch                  // 8 bytes
}
```

Here is the comparison, per validator, between storing a
`*ethpb.Validator` and a `CompactValidator`.

| Component | `*ethpb.Validator` | `CompactValidator` | Wasted |

|------------------------------------------|--------------------|--------------------|---------|
| Pointer to struct | 8 B | 0 B | 8 B |
| `state` (protoimpl.MessageState) | 8 B | 0 B | 8 B |
| `PublicKey` slice header (ptr+len+cap) | 24 B | 0 B | 24 B |
| `PublicKey` backing array (heap) | 48 B | 48 B (inline) | 0 B |
| `PublicKey` malloc overhead | ~16 B | 0 B | ~16 B |
| `WithdrawalCredentials` slice header | 24 B | 0 B | 24 B |
| `WithdrawalCredentials` backing array | 32 B | 32 B (inline) | 0 B |
| `WithdrawalCredentials` malloc overhead | ~16 B | 0 B | ~16 B |
| `EffectiveBalance` (uint64) | 8 B | 8 B | 0 B |
| `Slashed` (bool + padding) | 8 B | 8 B | 0 B |
| `ActivationEligibilityEpoch` | 8 B | 8 B | 0 B |
| `ActivationEpoch` | 8 B | 8 B | 0 B |
| `ExitEpoch` | 8 B | 8 B | 0 B |
| `WithdrawableEpoch` | 8 B | 8 B | 0 B |
| `unknownFields` ([]byte header) | 24 B | 0 B | 24 B |
| `sizeCache` (int32 + padding) | 8 B | 0 B | 8 B |
| Struct malloc overhead | ~16 B | 0 B | ~16 B |
| **Total** | **~264 B** | **128 B** | **~136 B (52%)** |

We waste `~136 B` per validator.
With a total of `2,229,313` validators (mainnet), it represents `~290
MB`.
Storing `CompactValidator` instead of `*ethpb.Validator` also reduces
the garbage collection pressure.

The following graph represents, for a Hoodi supernode (200 validators
managed):
1. The heap memory usage (`go_memstats_alloc_bytes`) without this PR
(`ref`) and with this PR (`current`)
2. `1.`, but averaged over the latest four hours.
3. The diff of the graphs in `2`. (The bigger, the better)

> [!NOTE]
> The improvement is, after stabilisation, **~300MB-450MB**,
representing **~8%-11%**.
>
> <img width="1028" height="917" alt="image"
src="https://github.com/user-attachments/assets/9179d9b1-bc50-4248-9f47-82a7646d58ab"
/>
>
> For some reasons, the gain is higher than initialy expected.

**For the reviewers:**
This PR should be reviewed commit by commit:
Commits 1 and 2 are independent and unrelated to this PR
Commit 3 is an oversight of:
- https://github.com/OffchainLabs/prysm/pull/16420

Commit 4 implements the `CompactValidator`
Commit 5 uses the `CompactValidator`. The key change is:
```go
// MultiValueValidators is a multi-value slice of compact validators.
type MultiValueValidators = multi_value_slice.Slice[stateutil.CompactValidator]
```

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: Bastin <43618253+Inspector-Butters@users.noreply.github.com>
2026-03-17 13:38:58 +00:00
terence
458d4ebe54 Use read only validator accessor in IsPayloadTimelyCommittee (#16530)
This PR replaces `ValidatorAtIndex` with `ValidatorAtIndexReadOnly` in
`IsPayloadTimelyCommittee` to avoid copying the entire validator on each
call

CPU and heap profiling of ePBS devnet nodes shows `PayloadCommittee` →
`CopyValidator` as the single largest hotspot, consuming ~18-20% of CPU
time across all servers. `IsPayloadTimelyCommittee` calls
`ValidatorAtIndex` in a loop over candidate committee members, and each
call deep-copies the full validator struct (~1 KB) only to read
`EffectiveBalance`

`ValidatorAtIndexReadOnly` returns a read-only reference to the
underlying validator, eliminating the copy. The only field accessed is
`EffectiveBalance()`, which is available on the read-only interface
2026-03-13 20:23:10 +00:00
terence
416c49e6d5 metrics: add initial gloas metric (#16519)
This PR adds an initial gloas metric

**Forkchoice**
- Add `forkchoice_payload_inserted_count`
- Add `forkchoice_payload_empty_node_count`
- Add `forkchoice_payload_full_node_count`
- Add `forkchoice_ptc_vote_count`

These metrics show how forkchoice evolves under Gloas:
- how many payload nodes are inserted
- how many currently tracked nodes represent empty payloads vs full
payloads
- how many PTC votes forkchoice receives

**Blockchain**
- Add `beacon_execution_payload_envelope_valid_total`
- Add `beacon_execution_payload_envelope_invalid_total`
- Add `beacon_execution_payload_envelope_processing_duration_seconds`
- Add `beacon_late_payload_task_triggered_total`

These metrics track the beacon node’s envelope handling:
- whether received execution payload envelopes are accepted or rejected
- how long envelope processing takes end-to-end
- how often the late payload task fires during the slot

**Sync**
- Add `sync_payload_attestation_arrival_delay_seconds`
- Add `sync_execution_payload_envelope_arrival_delay_seconds`
- Add `sync_payload_envelope_by_range_served_total`
- Add `sync_payload_envelope_by_root_served_total`
- Add `gloas_execution_payload_envelopes_rpc_requests_total{rpc,result}`

These metrics focus on network timing and RPC serving:
- how long after slot start payload attestations and payload envelopes
arrive over gossip
- how often payload envelope RPC requests are served
- how payload-envelope RPC requests break down by method and result

For gossip validation, only arrival delay remains:
- payload attestation
- execution payload envelope
- data column sidecar continues to use the existing generic arrival
metric

Custom sync-side gossip result counters were removed because libp2p
already accounts for validation outcomes.

**Payload Attestation Pool**
- Add `payload_attestation_pool_size`

This metric shows the current size of the payload attestation pool,
which is useful for seeing whether attestations are being accumulated or
drained as expected.

**Validator RPC**
- Add `gloas_payload_id_cache_total{result}`

This metric shows Gloas proposer payload ID cache behavior:
- cache hits
- cache misses

That helps explain whether proposers are reusing cached EL payload IDs
or falling back to fresh forkchoice updates.

**Validator Client**
- Add `validator_payload_attestation_submission_total{result}`
- Add `validator_self_build_envelope_submission_total{result}`

These metrics show validator-side Gloas behavior:
- whether payload attestation submissions succeed or fail
- whether self-build envelope submissions succeed or fail

**Core Gloas**
- Add `gloas_builder_pending_payments_processed_total`
- Add `gloas_builder_deposits_processed_total`

These metrics show builder-economics state transitions:
- how many pending builder payments are promoted into pending
withdrawals
- how many builder-related deposit requests are processed

**State Native**
- Add `gloas_execution_payload_availability_ratio`
- Add `gloas_builder_pending_withdrawals_count`
- Add `gloas_builder_pending_withdrawals_gwei`
- Add `gloas_payload_expected_withdrawals_count`
- Add `gloas_active_builders_count`
- Add `gloas_active_builders_balance_gwei`

These metrics expose the current Gloas state snapshot:
- how much of the payload availability window is marked available
- how many builder pending withdrawals exist and their total value
- how many expected withdrawals are cached for the next payload
- how many builders are currently active and their aggregate balance

These are emitted from `RecordStateMetrics()`
2026-03-13 16:07:01 +00:00
Manu NALEPA
84993fdd68 Fix TestProcessPendingDepositsMultiplesSameDeposits to properly test that duplicate pending deposits for the same key top up a single validator instead of creating duplicates. (#16529)
**What type of PR is this?**
Bug fix (in tests)

**What does this PR do? Why is it needed?**
Fix `TestProcessPendingDepositsMultiplesSameDeposits` to properly test
that duplicate pending deposits for the same key top up a single
validator instead of creating duplicates.

Previously, this test used 2 validators with the same pubkey.

**Acknowledgements**
- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-03-13 15:01:19 +00:00
terence
8d5d584cf8 sync,verification: add Gloas data column gossip validation path (#16515)
This PR adds a dedicated Gloas `data_column_sidecar` gossip validation
path and aligns it with the EIP-7732 spec.

The validation flow is now split cleanly:
- Fulu stays in the existing `validate_data_column` path
- Gloas moves into `validate_data_column_gloas`
- Gloas-specific checks live in a dedicated `GloasDataColumnVerifier`

**What Changed**
- Add a separate Gloas data column gossip validator in sync
- Add `GloasDataColumnVerifier` in `verification`
- Validate Gloas sidecars against
`block.body.signed_execution_payload_bid.message.blob_kzg_commitments`
- Refactor KZG proof verification to accept commitments explicitly
instead of rewriting the sidecar
- Use Gloas dedupe semantics: `(beacon_block_root, index)`
- Add spec-mapped comments next to the Gloas checks
- Add a TODO for deferred queue/revalidation when the block has not yet
been seen

**Spec Mapping**

The Gloas path now follows this order:
1. `IGNORE` if the block for `sidecar.beacon_block_root` has not been
seen
2. `REJECT` if `sidecar.slot != block.slot`
3. `REJECT` if `verify_data_column_sidecar(sidecar,
bid.blob_kzg_commitments)` fails
4. `REJECT` if the sidecar is on the wrong subnet
5. `REJECT` if `verify_data_column_sidecar_kzg_proofs(sidecar,
bid.blob_kzg_commitments)` fails
6. `IGNORE` if `(sidecar.beacon_block_root, sidecar.index)` has already
been seen

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2026-03-12 22:50:26 +00:00
james-prysm
0e4f3231d2 adding payload_attestation_message event (#16506)
**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

adds payload_attestation_message event triggered via grpc and gossip
message received, introduced in
https://github.com/ethereum/beacon-APIs/pull/552

**Which issues(s) does this PR fix?**

Fixes #

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [ ] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-03-11 16:24:53 +00:00
Potuz
e35f6c351a Handle missing Payloads (#16460)
In the event of a late missing Payload, we add a helper that updates the
beacon block post state in the NSC as well as handling the boundary
caches and calling FCU if we are proposing next slot.
2026-03-10 13:59:50 +00:00
terence
7a4bea0e44 rpc/validator: implement PayloadAttestationData and SubmitPayloadAttestation gRPC endpoints (#16487)
- This PR adds the payload attestation prototype flow. 
- On the proto side it introduces `PayloadAttestationDataRequest` and
two RPC methods on `BeaconNodeValidator`: `PayloadAttestationData` and
`SubmitPayloadAttestation`.
- The `ForkchoiceFetcher` interface is extended with
`HighestReceivedBlockRoot() [32]byte`, which returns the beacon block
root at the highest received slot and is used to determine which block
PTC members attest to, and `HasFullNode([32]byte) bool`, which indicates
whether a full payload node exists for a given root and determines the
`PayloadPresent` field in the response.
- The RPC server implementation lives in
`beacon-chain/rpc/prysm/v1alpha1/validator/payload_attestation.go`.
`PayloadAttestationData` validates the current slot, checks sync status,
and returns attestation data using the forkchoice helpers, while
`SubmitPayloadAttestation` validates the request, broadcasts it over
P2P, applies it locally through `ReceivePayloadAttestationMessage`, and
inserts it into the payload attestation pool. Wiring adds
`PayloadAttestationPool` and `PayloadAttestationReceiver` to `Server`,
`rpc.Config`, and `BeaconNode`, with the pool instantiated in
`node.New()`.
- Both RPCs are marked `deprecated = true` since this prototype will
eventually move to the beacon REST API.
2026-03-07 04:57:28 +00:00
Manu NALEPA
dc62271ebb Use InitializeFromProtoUnsafeXXX instead of InitializeFromProtoXXX when possible. (Nishant's optimization) (#16420)
**What type of PR is this?**
Optimisation

**What does this PR do? Why is it needed?**
Use `InitializeFromProtoUnsafeXXX` instead of `InitializeFromProtoXXX`
when possible. (@nisdas' change)
This change avoids useless copies.

The difference between these two methods is the latest copies the input
state. However, if the input state is guaranteed not to be modified
after the use of this function (and, in particular, if the input state
is not used at all after the use of this function), then copying it is
unnecessarry. ==> Using the "unsafe" method is fine in this case.

**Other notes for review**
As a reviewer, you should ensure that when the unsafe method is used,
then the input state is never modified after the use of the function.

This PR is much easier to review directly in VSCode, because it displays
more context by default.

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-03-06 15:46:34 +00:00
terence
a88f60f1fa Apply gloas payload state mutations during stategen replay (#16464)
State replay in gloas needs to reflect post-payload state even when
replay input is a blinded envelope format. Without applying these
mutations during stategen replay, reconstructed states can diverge from
the canonical post-payload state. At the same time, not every block has
an envelope, so replay must remain robust when envelope data is absent

Summary
- apply Gloas execution payload envelope state mutations during stategen
replay when a blinded envelope is available
- extract reusable payload-mutation logic into
`ApplyExecutionPayloadStateMutations` and use it from both normal
payload processing and stategen replay
2026-03-04 16:26:04 +00:00
Potuz
f7ead02e6e Make Dora Happy (#16441)
- This PR adds the execution_payload_envelope Beacon API endpoint
supporting both JSON and SSZ
- It add the execution_payload_available event stream 

it also adds as a stub without a trigger the execution_payload_bid event
stream.

These are the minimum necessary to get Dora happy on Kurtosis. Haven't
reviewed this PR yet, so opening it as draft. Only check was in Kurtosis
against Dora.

<img width="1555" height="1177" alt="Screenshot 2026-02-27 at 7 18
01 PM"
src="https://github.com/user-attachments/assets/e888ccf3-68fe-42c0-9f9a-f911438438d1"
/>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 01:12:58 +00:00
Potuz
17f1b78494 Better usage of the Next Slot cache in Gloas (#16439)
This PR exposes a function from the blockchain package to obtain a given
blocks's parent state.

It also fetches the correct state before processing slots to obtain the
prestate of a block.
2026-03-03 01:50:30 +00:00
terence
c114bc57d9 Implement gloas state transition and more spec tests (#16406) 2026-02-26 15:36:23 +00:00
terence
5b19916067 gloas: implement modified process withdrawals (#16310)
this PR implements [process
withdrawals](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#modified-process_withdrawals)for
gloas. In particular

* `process_withdrawals` signature changed from the last fork, moving
from `(state, payload)` to `(state)`. It now adds builder pending
withdrawals, sweeping withdrawals, and index updates, and removes the
payload check. Because of these drastic changes, I think it is more
beneficial to implement gloas process withdrawals from scratch rather
than overloading the electra function

* previously, for every withdrawal, we would lock and unlock state to
deduct validator balance. In this fork, when a withdrawal is for a
builder, we also decrease the builder balance. I improved this by encap
the whole logic under a state setter
`st.DecreaseWithdrawalBalances(expected.Withdrawals)`, which only locks
and unlocks once

* what's new are the following (in code order).. In
`process_withdrawals`

  * `IsParentBlockFull`
  * `ExpectedWithdrawalsGloas`
    * `appendBuilderWithdrawals`
    * `appendBuildersSweepWithdrawals`
  * `DecreaseWithdrawalBalances`
  * `SetPayloadExpectedWithdrawals`
  * `DequeueBuilderPendingWithdrawals`
  * `SetNextWithdrawalBuilderIndex`

* i passed withdrawals by reference as `*[]*enginev1.Withdrawal`. This
results in two slice header copies of 24 bytes. I find the cost
non-matter and the code more readable, but this can be changed if anyone
has a stronger opinion
2026-02-25 18:10:15 +00:00
james-prysm
fdd04a5466 gloas grpc proposer (#16336)
<!-- Thanks for sending a PR! Before submitting:

1. If this is your first PR, check out our contribution guide here
https://docs.prylabs.network/docs/contribute/contribution-guidelines
You will then need to sign our Contributor License Agreement (CLA),
which will show up as a comment from a bot in this pull request after
you open it. We cannot review code without a signed CLA.
2. Please file an associated tracking issue if this pull request is
non-trivial and requires context for our team to understand. All
features and most bug fixes should have
an associated issue with a design discussed and decided upon. Small bug
   fixes and documentation improvements don't need issues.
3. New features and bug fixes must have tests. Documentation may need to
be updated. If you're unsure what to update, send the PR, and we'll
discuss
   in review.
4. Note that PRs updating dependencies and new Go versions are not
accepted.
   Please file an issue instead.
5. A changelog entry is required for user facing issues.
-->

**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This PR defines the validator proposer paths for Gloas, namely adding
gloas fork support on the validator client for propose function, and
adding the following gRPC endpoint support: get Gloas Block, publish
Gloas Block, Get Payload Envelope, Publish Payload envelope.

we propose in this order

1. Get block (cache payload)
2. Submit block
3. Get payload (get post state of 2 via chain info getter) // needs the
block to be recieved and processed
4. Submit payload

There are several things still missing in the PR depending on
https://github.com/OffchainLabs/prysm/pull/15656 as well as future ones,
for now I have left those areas as TODO remarks

**Which issues(s) does this PR fix?**

Fixes #

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [ ] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: terence <terence@prysmaticlabs.com>
2026-02-24 19:16:45 +00:00
terence
d262c9f927 Implement upgrade gloas (#16378)
This PR ismplement Gloas fork upgrade. There are two main parts
- The first part is upgrade fulu state to gloas and including new gloas
fields
- The second part on board builder at the fork, which is a state setter
under one block. For this, we had to refactor a few things to be lock
free
- We also added spec tests for it to pass
2026-02-23 17:44:29 +00:00
kasey
b31e2ffe51 avoid copying the finalized state when computing cgc (#16355)
Reviewing some (unrelated) sync code today I noticed that we are using a
stategen accessor for the finalized state which copies the entire state
object to look up validator balances to compute the custody_group_count.
This excess memory allocation is likely causing GC pressure and
increasing memory utilization.

This PR avoids state copying for this purpose by making the following
changes:
- Adds a new method to the `ReadOnlyBalances` state interface:
`EffectiveBalances([]primitives.ValidatorIndex) (uint64, []uint64,
error)`. This method computes returns the sum of the effective balances
of the given list of validator indices, a list with the individual
effective balance of each requested index (where the i-th element in the
return corresponds to the i-th element of the parameter), and an error -
which is necessary due to index bounds checks and quirks of multi-value
slice that can apparently result in the state being unusable for such
lookups if not correctly initialized.
- Adds a new method to the stategen interface
`FinalizedReadOnlyBalances`, which returns the finalized state asserted
to the `ReadOnlyBalances` interface.
- Switches the peerdas code to use the sum given by `EffectiveBalances`.

There was some existing nil checking code in the peerdas package that I
didn't want to modify, so I added a new compound interface in stategen
to allow the returned state to also expose the `IsNil` method.

fixes https://github.com/OffchainLabs/prysm/issues/16354

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2026-02-17 08:50:58 +00:00
terence
22e77add54 Refactor function ProcessExecutionPayload with ApplyExecutionPayload (#16356)
This PR refactors `ProcessExecutionPayload` with `ApplyExecutionPayload`
so caller can use Apply method to calculate post state root. Note that
validations are not required for Apply function. We really need the
state mutation lines that's:
```
1. Ensure latest_block_header.state_root is set (if zero, set it to the pre‑payload HashTreeRoot)...
2. processExecutionRequests()
3. QueueBuilderPayment()
4. SetExecutionPayloadAvailability(state.Slot(), true)
5. SetLatestBlockHash(payload.BlockHash())
```
I decided to keep them there because a. it's cheap b. it makes refactor
cleaner to reason c. API/caller may want to validate envelope and bid
consistency (ex: beacon api has option to validate consensus)
2026-02-13 15:51:22 +00:00
terence
7f9983386e gloas: add new execution payload envelope processing (#15656)
This PR implements
[process_execution_payload](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_execution_payload)
and spec tests.
2026-02-12 21:56:41 +00:00
terence
6c045083a6 gloas: add modified attestation processing (#15736)
This PR implements
[process_attestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#modified-process_attestation)
alongside spec tests

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-02-11 23:22:42 +00:00
terence
9c49bb484c Add gossip for payload attestation (#16333)
This PR implements gossip validation and subscription for payload
attestation
2026-02-10 16:17:22 +00:00
terence
14f01bbc6c gloas: move kzg commitments to bid (#16309)
This PR moves kzg commitments to bid. The rationale behind is captured
in this [issue](https://github.com/ethereum/consensus-specs/issues/4870)
* Moves blob KZG commitments to the earlier point where builder intent
is known
* Removes duplicated commitments from data column sidecars which saves
descent b/w per slot
* Enables nodes to start fetching blobs via getBlobs as soon as the bid
is received
* Slightly increases bid size and may add minor bidding channel latency
but the tradeoff favors lower network load and simpler DA handling
2026-02-06 23:07:54 +00:00
Justin Traglia
fab687d96d Improve ethspecify integration (#16304)
**What type of PR is this?**

Documentation

**What does this PR do? Why is it needed?**

* Move the ethspecify config from `/specrefs/.ethspecify` to
`/.ethspecify`.
* This allows developers to use inline specrefs (eg spec functions in
godoc comments).
* To do this, simply add a spec tag and run `ethspecify` to populate it.
* Clean up specref exceptions; organize by upgrade & put items in the
correct section.
* Update a few godoc comments to use the new inline specref feature.
* Update check-specrefs GitHub action so that it enforces up-to-date
godocs.
* Standardize specref naming; requiring a `#fork` tag for everything.
* Add new specrefs (which haven't been implemented yet) which were
missing.

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2026-02-04 18:44:01 +00:00
terence
a7fdd11777 gloas: sample PTC per committee (#16293)
This PR updates `get_ptc` construction to sample ptc
committee-by-committee instead of concatenating all beacon committees
into a large slice. No functional changes to payload attestation
verification
2026-01-29 14:21:54 +00:00
terence
2cbb743606 gloas: add new payload attestation processing (#15650)
This PR implements
[process_payload_attestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_payload_attestation)
and spec tests
2026-01-27 03:34:12 +00:00
terence
42e5417a7b core: move EL requests to core/requests (#16280)
This PR moves consolidation and withdrawal request processing into
neutral package: `beacon-chain/core/requests`, such that they can be
shared between fork

Why?
Today our core packages are mixed between two workflows: older forks
calling into newer forks, and newer work calling back into older fork
code. No matter which direction we settle on long-term, a clear first
step is to move shared cross-fork functionality into a neutral place so
we can reuse it later such that if fork A and fork B interleave each
other, they can become clear abstractions

Why git mv wasn’t used for consolidations?
Withdrawals lived in a clean, dedicated file so it was moved with git
mv. Consolidation logic was interleaved with other Electra code and
needed extraction/refactor, so a pure git mv would not have preserved
meaningful history
2026-01-26 16:31:47 +00:00
terence
37b27fdd3c Move deposit helpers out of blocks to break blocks <-> gloas cycle (#16277)
- moves deposit-related helpers (deposit signature verification, batch
verification, merkle proof verification, and activation helper) from
`beacon-chain/core/blocks` into `beacon-chain/core/helpers`
- updates call sites (Altair/Electra) to use helpers

Why?
- In gloas, the blocks package needs to call into gloas logic (e.g.
clearing builder pending payments/withdrawals on proposer slashing)
- gloas also introduces deposit-request processing which needs deposit
signature verification previously located in blocks.
That creates a Bazel/Go dependency cycle (blocks -> gloas -> blocks)
- the natural layering is for blocks and fork logic to depend on a lower
level util package for deposit verification, so moving deposit helpers
to core/helpers breaks the cycle
2026-01-23 21:33:28 +00:00
terence
d440aafacf gloas: add modified proposer slashing processing (#16212)
This PR implements
[process_proposer_slashing](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#modified-process_proposer_slashing)
alongside spec tests
2026-01-22 15:38:55 +00:00
terence
fde63a217a gloas: add modified slot processing (#15730)
This PR implements
[process_slot](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#modified-process_slot)
and spec tests
2026-01-20 22:44:09 +00:00
terence
d33389fb54 gloas: add new pending payment processing (#15655)
This PR implements
[process_builder_pending_payments](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_builder_pending_payments)
and spec tests.
2026-01-16 21:19:06 +00:00
terence
a08f185170 gloas: add new execution payload bid processing (#15638)
This PR implements
[process_execution_payload_bid](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_execution_payload_bid)
and spec tests
2026-01-15 10:52:19 +00:00