|
| 1 | +use super::Error; |
| 2 | +use safe_arith::SafeArith; |
| 3 | +use types::{BeaconState, BuilderPendingPayment, ChainSpec, EthSpec, Vector}; |
| 4 | + |
| 5 | +pub fn process_builder_pending_payments<E: EthSpec>( |
| 6 | + state: &mut BeaconState<E>, |
| 7 | + spec: &ChainSpec, |
| 8 | +) -> Result<(), Error> { |
| 9 | + let quorum = get_builder_payment_quorum_threshold(state, spec)?; |
| 10 | + |
| 11 | + // Collect qualifying payments |
| 12 | + let qualifying_payments = state |
| 13 | + .builder_pending_payments()? |
| 14 | + .iter() |
| 15 | + .take(E::slots_per_epoch() as usize) |
| 16 | + .filter(|payment| payment.weight > quorum) |
| 17 | + .cloned() |
| 18 | + .collect::<Vec<_>>(); |
| 19 | + |
| 20 | + // Update `builder_pending_withdrawals` with qualifying `builder_pending_payments` |
| 21 | + qualifying_payments |
| 22 | + .into_iter() |
| 23 | + .try_for_each(|payment| -> Result<(), Error> { |
| 24 | + let exit_queue_epoch = |
| 25 | + state.compute_exit_epoch_and_update_churn(payment.withdrawal.amount, spec)?; |
| 26 | + let withdrawable_epoch = |
| 27 | + exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?; |
| 28 | + |
| 29 | + let mut withdrawal = payment.withdrawal.clone(); |
| 30 | + withdrawal.withdrawable_epoch = withdrawable_epoch; |
| 31 | + state.builder_pending_withdrawals_mut()?.push(withdrawal)?; |
| 32 | + Ok(()) |
| 33 | + })?; |
| 34 | + |
| 35 | + // Move remaining `builder_pending_payments` to start of list and set the rest to default |
| 36 | + let new_payments = state |
| 37 | + .builder_pending_payments()? |
| 38 | + .iter() |
| 39 | + .skip(E::slots_per_epoch() as usize) |
| 40 | + .cloned() |
| 41 | + .chain((0..E::slots_per_epoch() as usize).map(|_| BuilderPendingPayment::default())) |
| 42 | + .collect::<Vec<_>>(); |
| 43 | + |
| 44 | + *state.builder_pending_payments_mut()? = Vector::new(new_payments)?; |
| 45 | + |
| 46 | + Ok(()) |
| 47 | +} |
| 48 | + |
| 49 | +pub fn get_builder_payment_quorum_threshold<E: EthSpec>( |
| 50 | + state: &BeaconState<E>, |
| 51 | + spec: &ChainSpec, |
| 52 | +) -> Result<u64, Error> { |
| 53 | + let total_active_balance = state.get_total_active_balance()?; |
| 54 | + |
| 55 | + let quorum = total_active_balance |
| 56 | + .safe_div(E::slots_per_epoch())? |
| 57 | + .safe_mul(spec.builder_payment_threshold_numerator)?; |
| 58 | + |
| 59 | + quorum |
| 60 | + .safe_div(spec.builder_payment_threshold_denominator) |
| 61 | + .map_err(Error::from) |
| 62 | +} |
0 commit comments