merge with capella

This commit is contained in:
realbigsean
2022-12-23 10:21:18 -05:00
45 changed files with 164 additions and 231 deletions

View File

@@ -19,6 +19,7 @@ pub use process_operations::process_operations;
pub use verify_attestation::{
verify_attestation_for_block_inclusion, verify_attestation_for_state,
};
#[cfg(feature = "withdrawals-processing")]
pub use verify_bls_to_execution_change::verify_bls_to_execution_change;
pub use verify_deposit::{
get_existing_validator_index, verify_deposit_merkle_proof, verify_deposit_signature,
@@ -35,6 +36,7 @@ pub mod signature_sets;
pub mod tests;
mod verify_attestation;
mod verify_attester_slashing;
#[cfg(feature = "withdrawals-processing")]
mod verify_bls_to_execution_change;
mod verify_deposit;
mod verify_exit;
@@ -162,7 +164,7 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
// previous block.
if is_execution_enabled(state, block.body()) {
let payload = block.body().execution_payload()?;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))]
#[cfg(feature = "withdrawals-processing")]
process_withdrawals::<T, Payload>(state, payload, spec)?;
process_execution_payload::<T, Payload>(state, payload, spec)?;
}
@@ -466,8 +468,9 @@ pub fn compute_timestamp_at_slot<T: EthSpec>(
.and_then(|since_genesis| state.genesis_time().safe_add(since_genesis))
}
/// FIXME: add link to this function once the spec is stable
#[cfg(feature = "withdrawals")]
/// Compute the next batch of withdrawals which should be included in a block.
///
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-get_expected_withdrawals
pub fn get_expected_withdrawals<T: EthSpec>(
state: &BeaconState<T>,
spec: &ChainSpec,
@@ -481,7 +484,11 @@ pub fn get_expected_withdrawals<T: EthSpec>(
return Ok(withdrawals.into());
}
for _ in 0..state.validators().len() {
let bound = std::cmp::min(
state.validators().len() as u64,
spec.max_validators_per_withdrawals_sweep,
);
for _ in 0..bound {
let validator = state.get_validator(validator_index as usize)?;
let balance = *state.balances().get(validator_index as usize).ok_or(
BeaconStateError::BalancesOutOfBounds(validator_index as usize),
@@ -518,8 +525,8 @@ pub fn get_expected_withdrawals<T: EthSpec>(
Ok(withdrawals.into())
}
/// FIXME: add link to this function once the spec is stable
#[cfg(feature = "withdrawals")]
/// Apply withdrawals to the state.
#[cfg(feature = "withdrawals-processing")]
pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload<T>>(
state: &mut BeaconState<T>,
payload: Payload::Ref<'payload>,
@@ -547,11 +554,26 @@ pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload<T>
)?;
}
// Update the next withdrawal index if this block contained withdrawals
if let Some(latest_withdrawal) = expected_withdrawals.last() {
*state.next_withdrawal_index_mut()? = latest_withdrawal.index.safe_add(1)?;
let next_validator_index = latest_withdrawal
.validator_index
.safe_add(1)?
// Update the next validator index to start the next withdrawal sweep
if expected_withdrawals.len() == T::max_withdrawals_per_payload() {
// Next sweep starts after the latest withdrawal's validator index
let next_validator_index = latest_withdrawal
.validator_index
.safe_add(1)?
.safe_rem(state.validators().len() as u64)?;
*state.next_withdrawal_validator_index_mut()? = next_validator_index;
}
}
// Advance sweep by the max length of the sweep if there was not a full set of withdrawals
if expected_withdrawals.len() != T::max_withdrawals_per_payload() {
let next_validator_index = state
.next_withdrawal_validator_index()?
.safe_add(spec.max_validators_per_withdrawals_sweep)?
.safe_rem(state.validators().len() as u64)?;
*state.next_withdrawal_validator_index_mut()? = next_validator_index;
}

View File

@@ -170,7 +170,6 @@ where
// Deposits are not included because they can legally have invalid signatures.
self.include_exits(block)?;
self.include_sync_aggregate(block)?;
#[cfg(feature = "withdrawals")]
self.include_bls_to_execution_changes(block)?;
Ok(())
@@ -345,7 +344,6 @@ where
}
/// Include the signature of the block's BLS to execution changes for verification.
#[cfg(feature = "withdrawals")]
pub fn include_bls_to_execution_changes<Payload: AbstractExecPayload<T>>(
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,

View File

@@ -34,7 +34,7 @@ pub fn process_operations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
process_deposits(state, block_body.deposits(), spec)?;
process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))]
#[cfg(feature = "withdrawals-processing")]
if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() {
process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?;
}
@@ -295,6 +295,7 @@ pub fn process_exits<T: EthSpec>(
///
/// Returns `Ok(())` if the validation and state updates completed successfully. Otherwise returns
/// an `Err` describing the invalid object or cause of failure.
#[cfg(feature = "withdrawals-processing")]
pub fn process_bls_to_execution_changes<T: EthSpec>(
state: &mut BeaconState<T>,
bls_to_execution_changes: &[SignedBlsToExecutionChange],

View File

@@ -56,9 +56,7 @@ pub fn upgrade_to_capella<E: EthSpec>(
// Execution
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(),
// Withdrawals
#[cfg(feature = "withdrawals")]
next_withdrawal_index: 0,
#[cfg(feature = "withdrawals")]
next_withdrawal_validator_index: 0,
// Caches
total_active_balance: pre.total_active_balance,

View File

@@ -9,13 +9,7 @@ pub fn upgrade_to_eip4844<E: EthSpec>(
let epoch = pre_state.current_epoch();
let pre = pre_state.as_capella_mut()?;
// FIXME(sean) This is a hack to let us participate in testnets where capella doesn't exist.
// if we are disabling withdrawals, assume we should fork off of bellatrix.
let previous_fork_version = if cfg!(feature = "withdrawals") {
pre.fork.current_version
} else {
spec.bellatrix_fork_version
};
let previous_fork_version = pre.fork.current_version;
// Where possible, use something like `mem::take` to move fields from behind the &mut
// reference. For other fields that don't have a good default value, use `clone`.
@@ -64,9 +58,7 @@ pub fn upgrade_to_eip4844<E: EthSpec>(
// Execution
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(),
// Withdrawals
#[cfg(feature = "withdrawals")]
next_withdrawal_index: pre.next_withdrawal_index,
#[cfg(feature = "withdrawals")]
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
// Caches
total_active_balance: pre.total_active_balance,