Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions consensus/state_processing/src/per_epoch_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod capella;
pub mod effective_balance_updates;
pub mod epoch_processing_summary;
pub mod errors;
pub mod gloas;
pub mod historical_roots_update;
pub mod justification_and_finalization_state;
pub mod registry_updates;
Expand Down
6 changes: 6 additions & 0 deletions consensus/state_processing/src/per_epoch_processing/altair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::epoch_cache::initialize_epoch_cache;
use crate::per_epoch_processing::single_pass::{SinglePassConfig, process_epoch_single_pass};
use crate::per_epoch_processing::{
capella::process_historical_summaries_update,
gloas::process_builder_pending_payments,
historical_roots_update::process_historical_roots_update,
resets::{process_eth1_data_reset, process_randao_mixes_reset, process_slashings_reset},
};
Expand Down Expand Up @@ -77,6 +78,11 @@ pub fn process_epoch<E: EthSpec>(

process_sync_committee_updates(state, spec)?;

if state.builder_pending_payments().is_ok() {
// Post-Gloas
process_builder_pending_payments(state, spec)?;
}

// Rotate the epoch caches to suit the epoch transition.
state.advance_caches()?;
update_progressive_balances_on_epoch_transition(state, spec)?;
Expand Down
3 changes: 3 additions & 0 deletions consensus/state_processing/src/per_epoch_processing/gloas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub use process_builder_pending_payments::process_builder_pending_payments;

mod process_builder_pending_payments;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::EpochProcessingError;
use safe_arith::SafeArith;
use types::{BeaconState, BuilderPendingPayment, ChainSpec, EthSpec, Vector};

/// TODO(EIP-7732): Add EF consensus-spec tests for `process_builder_pending_payments`
/// Currently blocked by EF consensus-spec-tests for Gloas not yet integrated.
pub fn process_builder_pending_payments<E: EthSpec>(
state: &mut BeaconState<E>,
spec: &ChainSpec,
) -> Result<(), EpochProcessingError> {
let quorum = get_builder_payment_quorum_threshold(state, spec)?;

// Collect qualifying payments
let qualifying_payments = state
.builder_pending_payments()?
.iter()
.take(E::slots_per_epoch() as usize)
.filter(|payment| payment.weight > quorum)
.cloned()
.collect::<Vec<_>>();

// Update `builder_pending_withdrawals` with qualifying `builder_pending_payments`
qualifying_payments.into_iter().try_for_each(
|payment| -> Result<(), EpochProcessingError> {
let exit_queue_epoch =
state.compute_exit_epoch_and_update_churn(payment.withdrawal.amount, spec)?;
let withdrawable_epoch =
exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?;

let mut withdrawal = payment.withdrawal.clone();
withdrawal.withdrawable_epoch = withdrawable_epoch;
state.builder_pending_withdrawals_mut()?.push(withdrawal)?;
Ok(())
},
)?;

// Move remaining `builder_pending_payments` to start of list and set the rest to default
let new_payments = state
.builder_pending_payments()?
.iter()
.skip(E::slots_per_epoch() as usize)
.cloned()
.chain((0..E::slots_per_epoch() as usize).map(|_| BuilderPendingPayment::default()))
.collect::<Vec<_>>();

*state.builder_pending_payments_mut()? = Vector::new(new_payments)?;

Ok(())
}

pub fn get_builder_payment_quorum_threshold<E: EthSpec>(
state: &BeaconState<E>,
spec: &ChainSpec,
) -> Result<u64, EpochProcessingError> {
let total_active_balance = state.get_total_active_balance()?;

let quorum = total_active_balance
.safe_div(E::slots_per_epoch())?
.safe_mul(spec.builder_payment_threshold_numerator)?;

quorum
.safe_div(spec.builder_payment_threshold_denominator)
.map_err(EpochProcessingError::from)
}
19 changes: 19 additions & 0 deletions consensus/state_processing/src/per_slot_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum Error {
EpochProcessingError(EpochProcessingError),
ArithError(ArithError),
InconsistentStateFork(InconsistentFork),
BitfieldError(ssz::BitfieldError),
}

impl From<ArithError> for Error {
Expand All @@ -21,6 +22,12 @@ impl From<ArithError> for Error {
}
}

impl From<ssz::BitfieldError> for Error {
fn from(e: ssz::BitfieldError) -> Self {
Self::BitfieldError(e)
}
}

/// Advances a state forward by one slot, performing per-epoch processing if required.
///
/// If the root of the supplied `state` is known, then it can be passed as `state_root`. If
Expand Down Expand Up @@ -49,6 +56,18 @@ pub fn per_slot_processing<E: EthSpec>(

state.slot_mut().safe_add_assign(1)?;

// Unset the next payload availability
if state.fork_name_unchecked().gloas_enabled() {
let next_slot_index = state
.slot()
.as_usize()
.safe_add(1)?
.safe_rem(E::slots_per_historical_root())?;
state
.execution_payload_availability_mut()?
.set(next_slot_index, false)?;
}

// Process fork upgrades here. Note that multiple upgrades can potentially run
// in sequence if they are scheduled in the same Epoch (common in testnets)
if state.slot().safe_rem(E::slots_per_epoch())? == 0 {
Expand Down