Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
3fe2448
Proposer preferences uses checkpoint root
eserilev May 18, 2026
828b9c6
Use min seed lookahead for proposer preferences verification
eserilev May 18, 2026
08be7f5
Add payload_due_bps and relevant check
eserilev May 18, 2026
93bcd6c
count ptc votes from duplicated validators
eserilev May 18, 2026
b3ac2ff
MIN_BUILDER_WITHDRAWABILITY_DELAY update mainnet values
eserilev May 18, 2026
bb23439
track ptc participation
eserilev May 18, 2026
d2f26d3
allow proposer to re-org unavail blocks
eserilev May 18, 2026
45905dc
add target gas limit to paylaod attributes
eserilev May 18, 2026
53817f7
check bid gas limit consistency w/ target
eserilev May 18, 2026
d92b95a
fmt
eserilev May 18, 2026
d800535
cleanup
eserilev May 18, 2026
6a2dc05
add unit tests for is_gas_limit_target_compatible
eserilev May 18, 2026
c9a60b1
builder deposit optimization
eserilev May 18, 2026
49e83c3
FMT
eserilev May 18, 2026
3878543
Revert changes to ProposerPreferences
eserilev May 18, 2026
a693d56
Fix tests
eserilev May 18, 2026
f578674
Allow type com[plexity
eserilev May 18, 2026
e7eb8cd
update TODO
eserilev May 18, 2026
bc98ad1
Cleanup
eserilev May 18, 2026
98ed9b9
Fix fork choice issue
eserilev May 18, 2026
bcea7c9
fix
eserilev May 18, 2026
8926f61
Update
eserilev May 19, 2026
e82ef46
Revert some more changes
eserilev May 19, 2026
8d4f378
Another revert
eserilev May 19, 2026
26e3c69
Another revert
eserilev May 19, 2026
319c4e1
Revert
eserilev May 19, 2026
d9a5b5f
Revert
eserilev May 19, 2026
922b766
Revert
eserilev May 19, 2026
abff95b
Revert
eserilev May 19, 2026
583ced1
Revert'
eserilev May 19, 2026
b21645e
Another revert
eserilev May 19, 2026
21bd376
Re-intro set for validator pubkeys
eserilev May 19, 2026
3e4ab5a
Smol revert
eserilev May 19, 2026
f8fac6a
test_slot_component_duration_calculations
eserilev May 20, 2026
02a62d3
fork from env for gossip_verified_proposer_preferences.rs tests
eserilev May 20, 2026
7578e15
Remove footgun in validate_on_payload_attestation
eserilev May 20, 2026
48662dc
Add todo about inlininig validate_on_payload_attestation to make it l…
eserilev May 20, 2026
7ba6f03
Ensure payload_data_availability and payload_timeliness return errors…
eserilev May 20, 2026
e3b45c0
add clarifying comments to should_build_on_full
eserilev May 20, 2026
5603c79
just unwrap
eserilev May 20, 2026
015dcc3
saturating sub for calculating ptc participation - vote count
eserilev May 20, 2026
c9d5f7b
safe math
eserilev May 20, 2026
a4dbdf7
Claude
eserilev May 20, 2026
f27752f
warn if we fallback to parent gas limit
eserilev May 20, 2026
59068d7
parent gas limit should never be None
eserilev May 20, 2026
e690423
check payload_received in should_extend_payload
eserilev May 20, 2026
fce5898
move payload attestation current check to on_payload_attestation to m…
eserilev May 20, 2026
cb2c113
lint
eserilev May 20, 2026
2752356
add process wide fallback
eserilev May 21, 2026
800d05a
Use min seed lokahead fix
eserilev May 21, 2026
124f0c4
Clean up parent_gas_limit
michaelsproul May 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ use eth2::types::{
SseExtendedPayloadAttributes, SseHead,
};
use execution_layer::{
BlockProposalContents, BlockProposalContentsType, BuilderParams, ChainHealth, ExecutionLayer,
FailedCondition, PayloadAttributes, PayloadStatus,
BlockProposalContents, BlockProposalContentsType, BuilderParams, ChainHealth,
DEFAULT_GAS_LIMIT, ExecutionLayer, FailedCondition, PayloadAttributes, PayloadStatus,
};
use fixed_bytes::FixedBytesExtended;
use fork_choice::{
Expand Down Expand Up @@ -2185,12 +2185,20 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

// TODO(gloas) do we want to use a dedicated envelope cache instead?
// Maybe the new gloas DA cache? (Or should the gloas DA cache use
// the envelopes_times_cache internally?)
// the envelopes_times_cache internally?
// The payload is considered present only if it was observed before
// the payload due deadline (PAYLOAD_DUE_BPS into the slot).
let payload_due = self.spec.get_payload_due();
let payload_present = self
.envelope_times_cache
.read()
.cache
.contains_key(&beacon_block_root);
.get(&beacon_block_root)
.and_then(|entry| entry.timestamps.observed)
.is_some_and(|observed| {
let slot_start = self.slot_clock.start_of(request_slot);
slot_start.is_some_and(|start| observed.saturating_sub(start) < payload_due)
});

// TODO(EIP-7732): Check blob data availability. For now, default to true.
let blob_data_available = true;
Expand Down Expand Up @@ -6470,6 +6478,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
None
};

let target_gas_limit = if prepare_slot_fork.gloas_enabled() {
let proposer_gas_limit = execution_layer.get_proposer_gas_limit(proposer).await;
if proposer_gas_limit.is_none() {
warn!(
%proposer,
"No proposer gas limit configured, falling back to parent gas limit"
);
}
proposer_gas_limit.or(Some(DEFAULT_GAS_LIMIT))
} else {
None
};

let payload_attributes = PayloadAttributes::new(
self.slot_clock
.start_of(prepare_slot)
Expand All @@ -6480,6 +6501,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
withdrawals.map(Into::into),
parent_beacon_block_root,
slot_number,
target_gas_limit,
);

execution_layer
Expand Down
64 changes: 39 additions & 25 deletions beacon_node/beacon_chain/src/block_production/gloas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ use std::collections::{HashMap, HashSet};
use std::marker::PhantomData;
use std::sync::Arc;

use proto_array::PayloadStatus;

use bls::{PublicKeyBytes, Signature};
use execution_layer::{
BlockProposalContentsGloas, BuilderParams, PayloadAttributes, PayloadParameters,
BlockProposalContentsGloas, BuilderParams, DEFAULT_GAS_LIMIT, PayloadAttributes,
PayloadParameters,
};
use fork_choice::PayloadStatus;
use operation_pool::CompactAttestationRef;
use ssz::Encode;
use state_processing::common::{get_attesting_indices_from_state, get_indexed_payload_attestation};
Expand Down Expand Up @@ -150,8 +152,24 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
verification: ProduceBlockVerification,
builder_boost_factor: Option<u64>,
) -> Result<BlockProductionResult<T::EthSpec>, BlockProductionError> {
// Extract the parent's execution requests from the envelope (if parent was full).
let parent_execution_requests = if parent_payload_status == PayloadStatus::Full {
let parent_root = if state.slot() > 0 {
*state
.get_block_root(state.slot() - 1)
.map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)?
} else {
state.latest_block_header().canonical_root()
};

let should_build_on_full = self
.canonical_head
.fork_choice_read_lock()
.should_build_on_full(&parent_root, parent_payload_status)
.map_err(|e| {
BlockProductionError::BeaconChain(Box::new(BeaconChainError::ForkChoiceError(e)))
})?;

// Extract the parent's execution requests from the envelope (if building on full).
let parent_execution_requests = if should_build_on_full {
parent_envelope
.as_ref()
.map(|env| env.message.execution_requests.clone())
Expand Down Expand Up @@ -197,7 +215,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.clone()
.produce_execution_payload_bid(
state,
parent_payload_status,
should_build_on_full,
parent_envelope,
produce_at_slot,
BID_VALUE_SELF_BUILD,
Expand Down Expand Up @@ -700,12 +718,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// data needed to construct the `ExecutionPayloadEnvelope` after the beacon block is
/// created, plus the EL block value and `should_override_builder` flag used by the
/// caller to compare against any cached p2p builder bid.
#[allow(clippy::type_complexity)]
#[allow(clippy::type_complexity, clippy::too_many_arguments)]
#[instrument(level = "debug", skip_all)]
pub async fn produce_execution_payload_bid(
self: Arc<Self>,
state: BeaconState<T::EthSpec>,
parent_payload_status: PayloadStatus,
should_build_on_full: bool,
parent_envelope: Option<Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>>,
produce_at_slot: Slot,
bid_value: u64,
Expand Down Expand Up @@ -751,20 +769,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

let parent_bid = state.latest_execution_payload_bid()?;

// TODO(gloas): need should_extend_payload check here as well
let parent_block_slot = state.latest_block_header().slot;
let parent_is_pre_gloas = !self
.spec
.fork_name_at_slot::<T::EthSpec>(parent_block_slot)
.gloas_enabled();
let parent_block_hash =
if parent_payload_status == PayloadStatus::Full || parent_is_pre_gloas {
// Build on parent bid's payload.
parent_bid.block_hash
} else {
// Skip parent bid's payload. For genesis this is the EL genesis hash.
parent_bid.parent_block_hash
};
let parent_block_hash = if should_build_on_full || parent_is_pre_gloas {
// Build on parent bid's payload.
parent_bid.block_hash
} else {
// Skip parent bid's payload. For genesis this is the EL genesis hash.
parent_bid.parent_block_hash
};

// TODO(gloas) this should be BlockProductionVersion::V4
// V3 is okay for now as long as we're not connected to a builder
Expand Down Expand Up @@ -953,10 +969,7 @@ fn get_execution_payload_gloas<T: BeaconChainTypes>(
compute_timestamp_at_slot(state, state.slot(), spec).map_err(BeaconStateError::from)?;
let random = *state.get_randao_mix(current_epoch)?;

// TODO(gloas): this gas limit calc is not necessarily right
let parent_bid = state.latest_execution_payload_bid()?;
let latest_gas_limit = parent_bid.gas_limit;

let is_parent_block_full = parent_block_hash == parent_bid.block_hash;

let withdrawals = if is_parent_block_full {
Expand Down Expand Up @@ -992,7 +1005,6 @@ fn get_execution_payload_gloas<T: BeaconChainTypes>(
random,
proposer_index,
parent_block_hash,
latest_gas_limit,
builder_params,
withdrawals,
parent_beacon_block_root,
Expand Down Expand Up @@ -1020,7 +1032,6 @@ async fn prepare_execution_payload<T>(
random: Hash256,
proposer_index: u64,
parent_block_hash: ExecutionBlockHash,
parent_gas_limit: u64,
builder_params: BuilderParams,
withdrawals: Vec<Withdrawal>,
parent_beacon_block_root: Hash256,
Expand Down Expand Up @@ -1058,6 +1069,10 @@ where
.get_suggested_fee_recipient(proposer_index)
.await;
let slot_number = Some(builder_params.slot.as_u64());
let target_gas_limit = execution_layer
.get_proposer_gas_limit(proposer_index)
.await
.unwrap_or(DEFAULT_GAS_LIMIT);

let payload_attributes = PayloadAttributes::new(
timestamp,
Expand All @@ -1066,13 +1081,12 @@ where
Some(withdrawals),
Some(parent_beacon_block_root),
slot_number,
Some(target_gas_limit),
);

let target_gas_limit = execution_layer.get_proposer_gas_limit(proposer_index).await;
let payload_parameters = PayloadParameters {
parent_hash: parent_block_hash,
parent_gas_limit,
proposer_gas_limit: target_gas_limit,
parent_gas_limit: None,
proposer_gas_limit: Some(target_gas_limit),
payload_attributes: &payload_attributes,
forkchoice_update_params: &forkchoice_update_params,
current_fork: fork,
Expand Down
20 changes: 11 additions & 9 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
Ok(join_handle)
}

/// Prepares an execution payload for inclusion in a block.
/// Prepares an execution payload (pre-gloas) for inclusion in a block.
///
/// ## Errors
///
Expand Down Expand Up @@ -373,6 +373,13 @@ where
{
let spec = &chain.spec;
let fork = spec.fork_name_at_slot::<T::EthSpec>(builder_params.slot);

if fork.gloas_enabled() {
return Err(BlockProductionError::InvalidBlockVariant(
"Called pre-gloas prepare_execution_payload on a gloas block".to_string(),
));
}

let execution_layer = chain
.execution_layer
.as_ref()
Expand Down Expand Up @@ -403,25 +410,20 @@ where
.get_suggested_fee_recipient(proposer_index)
.await;

let slot_number = if fork.gloas_enabled() {
Some(builder_params.slot.as_u64())
} else {
None
};

Comment thread
michaelsproul marked this conversation as resolved.
let payload_attributes = PayloadAttributes::new(
timestamp,
random,
suggested_fee_recipient,
withdrawals,
parent_beacon_block_root,
slot_number,
None,
None,
);

let target_gas_limit = execution_layer.get_proposer_gas_limit(proposer_index).await;
let payload_parameters = PayloadParameters {
parent_hash,
parent_gas_limit: latest_execution_payload_header_gas_limit,
parent_gas_limit: Some(latest_execution_payload_header_gas_limit),
proposer_gas_limit: target_gas_limit,
payload_attributes: &payload_attributes,
forkchoice_update_params: &forkchoice_update_params,
Expand Down
Loading
Loading